From b456bfad5cee3922f55621bf7c133cc67337636a Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Fri, 12 Jul 2019 16:18:30 +0300 Subject: [PATCH] Add runtime GLES2 / Vulkan context selection. --- SConstruct | 2 - core/os/os.cpp | 6 +- core/os/os.h | 3 +- drivers/vulkan/rendering_device_vulkan.cpp | 17 +- drivers/vulkan/rendering_device_vulkan.h | 11 + main/main.cpp | 4 +- platform/osx/SCsub | 5 +- platform/osx/context_gl_osx.h | 79 +++ platform/osx/context_gl_osx.mm | 216 +++++++ platform/osx/detect.py | 26 +- platform/osx/os_osx.h | 10 +- platform/osx/os_osx.mm | 341 ++++------- platform/windows/SCsub | 9 +- platform/windows/detect.py | 35 +- platform/windows/os_windows.cpp | 193 +++--- platform/windows/os_windows.h | 5 +- platform/x11/SCsub | 2 +- platform/x11/detect.py | 15 +- platform/x11/os_x11.cpp | 577 +++++------------- platform/x11/os_x11.h | 13 +- .../rasterizer_rd/rasterizer_storage_rd.cpp | 4 + 21 files changed, 743 insertions(+), 830 deletions(-) create mode 100644 platform/osx/context_gl_osx.h create mode 100644 platform/osx/context_gl_osx.mm diff --git a/SConstruct b/SConstruct index be93d73b6d7..dfa60cda71f 100644 --- a/SConstruct +++ b/SConstruct @@ -112,8 +112,6 @@ opts.Add('platform', "Target platform (%s)" % ('|'.join(platform_list), ), '') opts.Add(EnumVariable('target', "Compilation target", 'debug', ('debug', 'release_debug', 'release'))) opts.Add(EnumVariable('optimize', "Optimization type", 'speed', ('speed', 'size'))) -opts.Add(EnumVariable('renderer', "Renderer type", 'vulkan', ('vulkan', 'opengl'))) - opts.Add(BoolVariable('tools', "Build the tools (a.k.a. the Godot editor)", True)) opts.Add(BoolVariable('use_lto', 'Use link-time optimization', False)) opts.Add(BoolVariable('use_precise_math_checks', 'Math checks use very precise epsilon (useful to debug the engine)', False)) diff --git a/core/os/os.cpp b/core/os/os.cpp index 0ce11516013..13be4a5c376 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -689,13 +689,11 @@ int OS::get_video_driver_count() const { const char *OS::get_video_driver_name(int p_driver) const { switch (p_driver) { - case VIDEO_DRIVER_VULKAN: - return "Vulkan"; case VIDEO_DRIVER_GLES2: return "GLES2"; - case VIDEO_DRIVER_GLES3: + case VIDEO_DRIVER_VULKAN: default: - return "GLES3"; + return "Vulkan"; } } diff --git a/core/os/os.h b/core/os/os.h index cd84b07de72..1bb910cb0d7 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -181,9 +181,8 @@ public: virtual void get_fullscreen_mode_list(List *p_list, int p_screen = 0) const = 0; enum VideoDriver { - VIDEO_DRIVER_GLES3, - VIDEO_DRIVER_GLES2, VIDEO_DRIVER_VULKAN, + VIDEO_DRIVER_GLES2, VIDEO_DRIVER_MAX, }; diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 4ca44283a32..77f4a294fa0 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -4905,7 +4905,9 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin_for_screen(in VkCommandBuffer command_buffer = frames[frame].draw_command_buffer; draw_list = memnew(DrawList); draw_list->command_buffer = command_buffer; +#ifdef DEBUG_ENABLED draw_list->validation.framebuffer_format = screen_get_framebuffer_format(); +#endif draw_list_count = 0; draw_list_split = false; @@ -5101,7 +5103,9 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu draw_list = memnew(DrawList); draw_list->command_buffer = command_buffer; +#ifdef DEBUG_ENABLED draw_list->validation.framebuffer_format = framebuffer->format_id; +#endif draw_list_count = 0; draw_list_split = false; @@ -5246,7 +5250,9 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p } draw_list[i].command_buffer = command_buffer; +#ifdef DEBUG_ENABLED draw_list[i].validation.framebuffer_format = framebuffer->format_id; +#endif VkViewport viewport; viewport.x = viewport_offset.x; @@ -5430,9 +5436,9 @@ void RenderingDeviceVulkan::draw_list_bind_vertex_array(DrawListID p_list, RID p #ifdef DEBUG_ENABLED dl->validation.vertex_format = vertex_array->description; - dl->validation.vertex_array_size = vertex_array->vertex_count; dl->validation.vertex_max_instances_allowed = vertex_array->max_instances_allowed; #endif + dl->validation.vertex_array_size = vertex_array->vertex_count; vkCmdBindVertexBuffers(dl->command_buffer, 0, vertex_array->buffers.size(), vertex_array->buffers.ptr(), vertex_array->offsets.ptr()); } void RenderingDeviceVulkan::draw_list_bind_index_array(DrawListID p_list, RID p_index_array) { @@ -5452,10 +5458,11 @@ void RenderingDeviceVulkan::draw_list_bind_index_array(DrawListID p_list, RID p_ dl->state.index_array = p_index_array; #ifdef DEBUG_ENABLED - dl->validation.index_array_size = index_array->indices; dl->validation.index_array_max_index = index_array->max_index; - dl->validation.index_array_offset = index_array->offset; #endif + dl->validation.index_array_size = index_array->indices; + dl->validation.index_array_offset = index_array->offset; + vkCmdBindIndexBuffer(dl->command_buffer, index_array->buffer, index_array->offset, index_array->index_type); } @@ -5463,7 +5470,9 @@ void RenderingDeviceVulkan::draw_list_set_line_width(DrawListID p_list, float p_ DrawList *dl = _get_draw_list_ptr(p_list); ERR_FAIL_COND(!dl); +#ifdef DEBUG_ENABLED ERR_FAIL_COND_MSG(!dl->validation.active, "Submitted Draw Lists can no longer be modified."); +#endif vkCmdSetLineWidth(dl->command_buffer, p_width); } @@ -5481,7 +5490,9 @@ void RenderingDeviceVulkan::draw_list_set_push_constant(DrawListID p_list, void "This render pipeline requires (" + itos(dl->validation.pipeline_push_constant_size) + ") bytes of push constant data, supplied: (" + itos(p_data_size) + ")"); #endif vkCmdPushConstants(dl->command_buffer, dl->state.pipeline_layout, dl->state.pipeline_push_constant_stages, 0, p_data_size, p_data); +#ifdef DEBUG_ENABLED dl->validation.pipeline_push_constant_suppplied = true; +#endif } void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances) { diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 547734a6bb6..690abeb0b30 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -767,6 +767,17 @@ class RenderingDeviceVulkan : public RenderingDevice { pipeline_push_constant_suppplied = false; } } validation; +#else + struct Validation { + uint32_t vertex_array_size; //0 if not set + uint32_t index_array_size; //0 if index buffer not set + uint32_t index_array_offset; + + Validation() { + vertex_array_size = 0; + index_array_size = 0; //not sent + } + } validation; #endif }; diff --git a/main/main.cpp b/main/main.cpp index 8b44984014b..9aebc17a651 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -990,8 +990,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->set_cmdline(execpath, main_args); - GLOBAL_DEF("rendering/quality/driver/driver_name", "GLES3"); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/driver/driver_name", PropertyInfo(Variant::STRING, "rendering/quality/driver/driver_name", PROPERTY_HINT_ENUM, "GLES2,GLES3,Vulkan")); + GLOBAL_DEF("rendering/quality/driver/driver_name", "Vulkan"); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/driver/driver_name", PropertyInfo(Variant::STRING, "rendering/quality/driver/driver_name", PROPERTY_HINT_ENUM, "Vulkan,GLES2")); if (video_driver == "") { video_driver = GLOBAL_GET("rendering/quality/driver/driver_name"); } diff --git a/platform/osx/SCsub b/platform/osx/SCsub index 2632c4f0325..09f213cb0e3 100644 --- a/platform/osx/SCsub +++ b/platform/osx/SCsub @@ -13,11 +13,10 @@ files = [ 'dir_access_osx.mm', 'joypad_osx.cpp', 'power_osx.cpp', + 'vulkan_context_osx.mm', + 'context_gl_osx.mm' ] -if (env["renderer"] == "vulkan"): - files += ['vulkan_context_osx.mm'] - prog = env.add_program('#bin/godot', files) if (env["debug_symbols"] == "full" or env["debug_symbols"] == "yes") and env["separate_debug_symbols"]: diff --git a/platform/osx/context_gl_osx.h b/platform/osx/context_gl_osx.h new file mode 100644 index 00000000000..831a813fe9c --- /dev/null +++ b/platform/osx/context_gl_osx.h @@ -0,0 +1,79 @@ +/*************************************************************************/ +/* context_gl_osx.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef CONTEXT_GL_OSX_H +#define CONTEXT_GL_OSX_H + +#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED) + +#include "core/error_list.h" +#include "core/os/os.h" + +#include +#include +#include + +class ContextGL_OSX { + + bool opengl_3_context; + bool use_vsync; + + void *framework; + id window_view; + NSOpenGLPixelFormat *pixelFormat; + NSOpenGLContext *context; + +public: + bool waiting_for_vsync; + NSCondition *vsync_condition; + CVDisplayLinkRef displayLink; + + void release_current(); + + void make_current(); + void update(); + + void set_opacity(GLint p_opacity); + + int get_window_width(); + int get_window_height(); + void swap_buffers(); + + Error initialize(); + + void set_use_vsync(bool p_use); + bool is_using_vsync() const; + + ContextGL_OSX(id p_view, bool p_opengl_3_context); + ~ContextGL_OSX(); +}; + +#endif +#endif \ No newline at end of file diff --git a/platform/osx/context_gl_osx.mm b/platform/osx/context_gl_osx.mm new file mode 100644 index 00000000000..425c9b0ac40 --- /dev/null +++ b/platform/osx/context_gl_osx.mm @@ -0,0 +1,216 @@ +/*************************************************************************/ +/* context_gl_osx.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "context_gl_osx.h" + +#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED) + +// DisplayLinkCallback is called from our DisplayLink OS thread informing us right before +// a screen update is required. We can use it to work around the broken vsync. +static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *now, const CVTimeStamp *outputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext) { + ContextGL_OSX *gl_ctx = (ContextGL_OSX *)displayLinkContext; + + // Set flag so we know we can output our next frame and signal our conditional lock + // if we're not doing vsync this will be ignored + [gl_ctx->vsync_condition lock]; + gl_ctx->waiting_for_vsync = false; + [gl_ctx->vsync_condition signal]; + [gl_ctx->vsync_condition unlock]; + + return kCVReturnSuccess; +} + +void ContextGL_OSX::release_current() { + + [NSOpenGLContext clearCurrentContext]; +} + +void ContextGL_OSX::make_current() { + + [context makeCurrentContext]; +} + +void ContextGL_OSX::update() { + + [context update]; +} + +void ContextGL_OSX::set_opacity(GLint p_opacity) { + + [context setValues:&p_opacity forParameter:NSOpenGLCPSurfaceOpacity]; +} + +int ContextGL_OSX::get_window_width() { + + return OS::get_singleton()->get_video_mode().width; +} + +int ContextGL_OSX::get_window_height() { + + return OS::get_singleton()->get_video_mode().height; +} + +void ContextGL_OSX::swap_buffers() { + + if (use_vsync) { + // Wait until our DisplayLink callback unsets our flag... + [vsync_condition lock]; + while (waiting_for_vsync) + [vsync_condition wait]; + + // Make sure we wait again next frame around + waiting_for_vsync = true; + + [vsync_condition unlock]; + } + + [context flushBuffer]; +} + +void ContextGL_OSX::set_use_vsync(bool p_use) { + // CGLCPSwapInterval broke in OSX 10.14 and it seems Apple is not interested in fixing + // it as OpenGL is now deprecated and Metal solves this differently. + // Following SDLs example we're working around this using DisplayLink + // When vsync is enabled we set a flag "waiting_for_vsync" to true. + // This flag is set to false when DisplayLink informs us our display is about to refresh. + + ///TODO Maybe pause/unpause display link? + use_vsync = p_use; + waiting_for_vsync = p_use; +} + +bool ContextGL_OSX::is_using_vsync() const { + + return use_vsync; +} + +Error ContextGL_OSX::initialize() { + + framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); + ERR_FAIL_COND_V(!framework, ERR_CANT_CREATE); + + unsigned int attributeCount = 0; + + // OS X needs non-zero color size, so set reasonable values + int colorBits = 32; + + // Fail if a robustness strategy was requested + +#define ADD_ATTR(x) \ + { attributes[attributeCount++] = x; } +#define ADD_ATTR2(x, y) \ + { \ + ADD_ATTR(x); \ + ADD_ATTR(y); \ + } + + // Arbitrary array size here + NSOpenGLPixelFormatAttribute attributes[40]; + + ADD_ATTR(NSOpenGLPFADoubleBuffer); + ADD_ATTR(NSOpenGLPFAClosestPolicy); + + if (!opengl_3_context) { + ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy); + } else { + //we now need OpenGL 3 or better, maybe even change this to 3_3Core ? + ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); + } + + ADD_ATTR2(NSOpenGLPFAColorSize, colorBits); + + /* + if (fbconfig->alphaBits > 0) + ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); +*/ + + ADD_ATTR2(NSOpenGLPFADepthSize, 24); + + ADD_ATTR2(NSOpenGLPFAStencilSize, 8); + + /* + if (fbconfig->stereo) + ADD_ATTR(NSOpenGLPFAStereo); +*/ + + /* + if (fbconfig->samples > 0) { + ADD_ATTR2(NSOpenGLPFASampleBuffers, 1); + ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples); + } +*/ + + // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB + // framebuffer, so there's no need (and no way) to request it + + ADD_ATTR(0); + +#undef ADD_ATTR +#undef ADD_ATTR2 + + pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; + ERR_FAIL_COND_V(pixelFormat == nil, ERR_CANT_CREATE); + + context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; + + ERR_FAIL_COND_V(context == nil, ERR_CANT_CREATE); + + [context setView:window_view]; + + [context makeCurrentContext]; + + // setup our display link, this will inform us when a refresh is needed + CVDisplayLinkCreateWithActiveCGDisplays(&displayLink); + CVDisplayLinkSetOutputCallback(displayLink, &DisplayLinkCallback, this); + CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, context.CGLContextObj, pixelFormat.CGLPixelFormatObj); + CVDisplayLinkStart(displayLink); + + // initialise a conditional lock object + vsync_condition = [[NSCondition alloc] init]; + + return OK; +} + +ContextGL_OSX::ContextGL_OSX(id p_view, bool p_opengl_3_context) { + + opengl_3_context = p_opengl_3_context; + window_view = p_view; + use_vsync = false; +} + +ContextGL_OSX::~ContextGL_OSX() { + + if (displayLink) { + CVDisplayLinkRelease(displayLink); + } + [vsync_condition release]; +} + +#endif diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 989bf6d425d..c4e87795238 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -154,20 +154,16 @@ def configure(env): env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreMIDI', '-framework', 'IOKit', '-framework', 'ForceFeedback', '-framework', 'CoreVideo', '-framework', 'AVFoundation', '-framework', 'CoreMedia']) env.Append(LIBS=['pthread', 'z']) - if (env["renderer"] == "vulkan"): - env.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"]) - env.Append(CPPDEFINES=['VULKAN_ENABLED']) - env.Append(LINKFLAGS=['-framework', 'Metal', '-framework', 'QuartzCore', '-framework', 'IOSurface']) - if (env['use_static_mvk']): - env.Append(LINKFLAGS=['-framework', 'MoltenVK']) - elif not env["builtin_vulkan_loader"]: - env.Append(LIBS=['vulkan']) + env.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"]) + env.Append(CPPDEFINES=['VULKAN_ENABLED']) - env.Append(CCFLAGS=['-mmacosx-version-min=10.11']) - env.Append(LINKFLAGS=['-mmacosx-version-min=10.11']) - else: - env.Append(CPPDEFINES=['GLES_ENABLED']) - env.Append(LINKFLAGS=['-framework', 'OpenGL', '-framework', 'AGL']) + #env.Append(CPPDEFINES=['GLES_ENABLED', 'OPENGL_ENABLED']) - env.Append(CCFLAGS=['-mmacosx-version-min=10.9']) - env.Append(LINKFLAGS=['-mmacosx-version-min=10.9']) + env.Append(LINKFLAGS=['-framework', 'Metal', '-framework', 'QuartzCore', '-framework', 'IOSurface']) + if (env['use_static_mvk']): + env.Append(LINKFLAGS=['-framework', 'MoltenVK']) + elif not env["builtin_vulkan_loader"]: + env.Append(LIBS=['vulkan']) + + env.Append(CCFLAGS=['-mmacosx-version-min=10.11']) + env.Append(LINKFLAGS=['-mmacosx-version-min=10.11']) diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 97da467ce46..00fc56def60 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -46,6 +46,10 @@ #include "servers/visual/visual_server_wrap_mt.h" #include "servers/visual_server.h" +#if defined(OPENGL_ENABLED) +#include "context_gl_osx.h" +#endif + #if defined(VULKAN_ENABLED) #include "drivers/vulkan/rendering_device_vulkan.h" #include "platform/osx/vulkan_context_osx.h" @@ -110,14 +114,12 @@ public: id cursor; #if defined(OPENGL_ENABLED) - void *framework; - NSOpenGLPixelFormat *pixelFormat; - NSOpenGLContext *context; + ContextGL_OSX *context_gles2; #endif #if defined(VULKAN_ENABLED) VulkanContextOSX *context_vulkan; - RenderingDeviceVulkan *rendering_device; + RenderingDeviceVulkan *rendering_device_vulkan; #endif bool layered_window; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 5a64aa56989..5d2bc5172fb 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -37,10 +37,10 @@ #if defined(OPENGL_ENABLED) #include "drivers/gles2/rasterizer_gles2.h" -#include "drivers/gles3/rasterizer_gles3.h" #endif + #if defined(VULKAN_ENABLED) -#include "servers/visual/rasterizer/rasterizer_rd.h" +#include "servers/visual/rasterizer_rd/rasterizer_rd.h" #endif #include "main/main.h" @@ -271,29 +271,6 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { return NSTerminateCancel; } -- (void)applicationDidHide:(NSNotification *)notification { - /* - _Godotwindow* window; - for (window = _Godot.windowListHead; window; window = window->next) - _GodotInputWindowVisibility(window, GL_FALSE); -*/ -} - -- (void)applicationDidUnhide:(NSNotification *)notification { - /* - _Godotwindow* window; - - for (window = _Godot.windowListHead; window; window = window->next) { - if ([window_object isVisible]) - _GodotInputWindowVisibility(window, GL_TRUE); - } -*/ -} - -- (void)applicationDidChangeScreenParameters:(NSNotification *)notification { - //_GodotInputMonitorChange(); -} - - (void)showAbout:(id)sender { if (OS_OSX::singleton->get_main_loop()) OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_ABOUT); @@ -347,11 +324,14 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { NSWindow *window = (NSWindow *)[notification object]; CGFloat newBackingScaleFactor = [window backingScaleFactor]; CGFloat oldBackingScaleFactor = [[[notification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue]; + #if defined(OPENGL_ENABLED) - if (OS_OSX::singleton->is_hidpi_allowed()) { - [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:YES]; - } else { - [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:NO]; + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_GLES2) { + if (OS_OSX::singleton->is_hidpi_allowed()) { + [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:YES]; + } else { + [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:NO]; + } } #endif @@ -374,10 +354,12 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { } - (void)windowDidResize:(NSNotification *)notification { -#if defined(OPENGL_ENABLED) - [OS_OSX::singleton->context update]; -#endif +#if defined(OPENGL_ENABLED) + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_GLES2) { + OS_OSX::singleton->context_gles2->update(); + } +#endif const NSRect contentRect = [OS_OSX::singleton->window_view frame]; const NSRect fbRect = contentRect; @@ -386,9 +368,11 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { OS_OSX::singleton->window_size.height = fbRect.size.height * displayScale; #if defined(VULKAN_ENABLED) - CALayer* layer = [OS_OSX::singleton->window_view layer]; - layer.contentsScale = OS_OSX::singleton->_display_scale(); - OS_OSX::singleton->context_vulkan->window_resize(0, OS_OSX::singleton->window_size.width, OS_OSX::singleton->window_size.height); + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_VULKAN) { + CALayer* layer = [OS_OSX::singleton->window_view layer]; + layer.contentsScale = OS_OSX::singleton->_display_scale(); + OS_OSX::singleton->context_vulkan->window_resize(0, OS_OSX::singleton->window_size.width, OS_OSX::singleton->window_size.height); + } #endif if (OS_OSX::singleton->main_loop) { @@ -398,15 +382,6 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { Main::iteration(); } } - - /* - _GodotInputFramebufferSize(window, fbRect.size.width, fbRect.size.height); - _GodotInputWindowSize(window, contentRect.size.width, contentRect.size.height); - _GodotInputWindowDamage(window); - - if (window->cursorMode == Godot_CURSOR_DISABLED) - centerCursor(window); -*/ } - (void)windowDidMove:(NSNotification *)notification { @@ -414,17 +389,6 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { if (OS_OSX::singleton->get_main_loop()) { OS_OSX::singleton->input->release_pressed_events(); } - - /* - [window->nsgl.context update]; - - int x, y; - _GodotPlatformGetWindowPos(window, &x, &y); - _GodotInputWindowPos(window, x, y); - - if (window->cursorMode == Godot_CURSOR_DISABLED) - centerCursor(window); -*/ } - (void)windowDidBecomeKey:(NSNotification *)notification { @@ -489,21 +453,25 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { - (CALayer*)makeBackingLayer { #if defined(VULKAN_ENABLED) - CALayer* layer = [[CAMetalLayer class] layer]; - layer.contentsScale = OS_OSX::singleton->_display_scale(); - return layer; + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_VULKAN) { + CALayer* layer = [[CAMetalLayer class] layer]; + layer.contentsScale = OS_OSX::singleton->_display_scale(); + return layer; + } #endif -#if defined(OPENGL_ENABLED) return [super makeBackingLayer]; -#endif } - (void)updateLayer { -#if defined(OPENGL_ENABLED) - [OS_OSX::singleton->context update]; -#endif #if defined(VULKAN_ENABLED) - [super updateLayer]; + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_VULKAN) { + [super updateLayer]; + } +#endif +#if defined(OPENGL_ENABLED) + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_GLES2) { + OS_OSX::singleton->context_gles2->update(); + } #endif } @@ -1499,6 +1467,14 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a // Register to be notified on displays arrangement changes CGDisplayRegisterReconfigurationCallback(displays_arrangement_changed, NULL); + //!!!!!!!!!!!!!!!!!!!!!!!!!! + //TODO - do Vulkan and GLES2 support checks, driver selection and fallback + video_driver_index = p_video_driver; + print_verbose("Driver: " + String(get_video_driver_name(video_driver_index)) + " [" + itos(video_driver_index) + "]"); + //!!!!!!!!!!!!!!!!!!!!!!!!!! + + //Create window + window_delegate = [[GodotWindowDelegate alloc] init]; // Don't use accumulation buffer support; it's not accelerated @@ -1540,15 +1516,15 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a if (displayScale > 1.0) { #if defined(OPENGL_ENABLED) - [window_view setWantsBestResolutionOpenGLSurface:YES]; + if (video_driver_index == VIDEO_DRIVER_GLES2) { + [window_view setWantsBestResolutionOpenGLSurface:YES]; + } #endif - //if (current_videomode.resizable) [window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; } else { [window_view setWantsBestResolutionOpenGLSurface:NO]; } - //[window_object setTitle:[NSString stringWithUTF8String:"GodotEnginies"]]; [window_object setContentView:window_view]; [window_object setDelegate:window_delegate]; [window_object setAcceptsMouseMovedEvents:YES]; @@ -1556,80 +1532,50 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a [window_object setRestorable:NO]; + // Init context and rendering device #if defined(OPENGL_ENABLED) - framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); - ERR_FAIL_COND(!framework); + if (video_driver_index == VIDEO_DRIVER_GLES2) { - unsigned int attributeCount = 0; + context_gles2 = memnew(ContextGL_OSX(window_view, false)); - // OS X needs non-zero color size, so set reasonable values - int colorBits = 32; + if (context_gles2->initialize() != OK) { + memdelete(context_gles2); + context_gles2 = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } - // Fail if a robustness strategy was requested -#define ADD_ATTR(x) \ - { attributes[attributeCount++] = x; } -#define ADD_ATTR2(x, y) \ - { \ - ADD_ATTR(x); \ - ADD_ATTR(y); \ + context_gles2->set_use_vsync(p_desired.use_vsync); + + if (RasterizerGLES2::is_viable() == OK) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + } else { + memdelete(context_gles2); + context_gles2 = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } } +#endif +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { - // Arbitrary array size here - NSOpenGLPixelFormatAttribute attributes[40]; + context_vulkan = memnew(VulkanContextOSX); + if (context_vulkan->initialize() != OK) { + memdelete(context_vulkan); + context_vulkan = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } + if (context_vulkan->window_create(window_view, get_video_mode().width, get_video_mode().height) == -1) { + memdelete(context_vulkan); + context_vulkan = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } - ADD_ATTR(NSOpenGLPFADoubleBuffer); - ADD_ATTR(NSOpenGLPFAClosestPolicy); + rendering_device_vulkan = memnew(RenderingDeviceVulkan); + rendering_device_vulkan->initialize(context_vulkan); - if (p_video_driver == VIDEO_DRIVER_GLES2) { - ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy); - } else { - //we now need OpenGL 3 or better, maybe even change this to 3_3Core ? - ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); + RasterizerRD::make_current(); } - - ADD_ATTR2(NSOpenGLPFAColorSize, colorBits); - - /* - if (fbconfig->alphaBits > 0) - ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); -*/ - - ADD_ATTR2(NSOpenGLPFADepthSize, 24); - - ADD_ATTR2(NSOpenGLPFAStencilSize, 8); - - /* - if (fbconfig->stereo) - ADD_ATTR(NSOpenGLPFAStereo); -*/ - - /* - if (fbconfig->samples > 0) { - ADD_ATTR2(NSOpenGLPFASampleBuffers, 1); - ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples); - } -*/ - - // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB - // framebuffer, so there's no need (and no way) to request it - - ADD_ATTR(0); - -#undef ADD_ATTR -#undef ADD_ATTR2 - - pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; - ERR_FAIL_COND_V(pixelFormat == nil, ERR_UNAVAILABLE); - - context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; - - ERR_FAIL_COND_V(context == nil, ERR_UNAVAILABLE); - - [context setView:window_view]; - - [context makeCurrentContext]; - - set_use_vsync(p_desired.use_vsync); #endif [NSApp activateIgnoringOtherApps:YES]; @@ -1641,67 +1587,6 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a if (p_desired.fullscreen) zoomed = true; - /*** END OSX INITIALIZATION ***/ - -#if defined(OPENGL_ENABLED) - bool gles3 = true; - if (p_video_driver == VIDEO_DRIVER_GLES2) { - gles3 = false; - } - - bool editor = Engine::get_singleton()->is_editor_hint(); - bool gl_initialization_error = false; - - while (true) { - if (gles3) { - if (RasterizerGLES3::is_viable() == OK) { - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - break; - } else { - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2") || editor) { - p_video_driver = VIDEO_DRIVER_GLES2; - gles3 = false; - continue; - } else { - gl_initialization_error = true; - break; - } - } - } else { - if (RasterizerGLES2::is_viable() == OK) { - RasterizerGLES2::register_config(); - RasterizerGLES2::make_current(); - break; - } else { - gl_initialization_error = true; - break; - } - } - } - - if (gl_initialization_error) { - OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n" - "Please update your drivers or if you have a very old or integrated GPU upgrade it.", - "Unable to initialize Video driver"); - return ERR_UNAVAILABLE; - } - - video_driver_index = p_video_driver; -#endif -#if defined(VULKAN_ENABLED) - video_driver_index = VIDEO_DRIVER_VULKAN; - - context_vulkan = memnew(VulkanContextOSX); - context_vulkan->initialize(); - context_vulkan->window_create(window_view, get_video_mode().width, get_video_mode().height); - - //temporary - rendering_device = memnew(RenderingDeviceVulkan); - rendering_device->initialize(context_vulkan); - RasterizerRD::make_current(); -#endif - visual_server = memnew(VisualServerRaster); if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); @@ -1734,6 +1619,27 @@ void OS_OSX::finalize() { midi_driver.close(); #endif +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + + if (context_gles2) + memdelete(context_gles2); + } +#endif +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + + if (rendering_device_vulkan) { + rendering_device_vulkan->finalize(); + memdelete(rendering_device_vulkan); + } + + if (context_vulkan) + memdelete(context_vulkan); + + } +#endif + CFNotificationCenterRemoveObserver(CFNotificationCenterGetDistributedCenter(), NULL, kTISNotifySelectedKeyboardInputSourceChanged, NULL); CGDisplayRemoveReconfigurationCallback(displays_arrangement_changed, NULL); @@ -1745,15 +1651,6 @@ void OS_OSX::finalize() { cursors_cache.clear(); visual_server->finish(); memdelete(visual_server); - -#if defined(VULKAN_ENABLED) - rendering_device->finalize(); - memdelete(rendering_device); - - memdelete(context_vulkan); -#endif - - //memdelete(rasterizer); } void OS_OSX::set_main_loop(MainLoop *p_main_loop) { @@ -2298,13 +2195,17 @@ String OS_OSX::get_clipboard() const { void OS_OSX::release_rendering_thread() { #if defined(OPENGL_ENABLED) - [NSOpenGLContext clearCurrentContext]; + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->release_current(); + } #endif } void OS_OSX::make_rendering_thread() { #if defined(OPENGL_ENABLED) - [context makeCurrentContext]; + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->make_current(); + } #endif } @@ -2320,10 +2221,15 @@ String OS_OSX::get_locale() const { } void OS_OSX::swap_buffers() { - [context flushBuffer]; +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->swap_buffers(); + } #endif #if defined(VULKAN_ENABLED) - context_vulkan->swap_buffers(); + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + context_vulkan->swap_buffers(); + } #endif } @@ -2738,8 +2644,9 @@ void OS_OSX::set_window_per_pixel_transparency_enabled(bool p_enabled) { [window_object setOpaque:NO]; [window_object setHasShadow:NO]; #if defined(OPENGL_ENABLED) - GLint opacity = 0; - [context setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity]; + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->set_opacity(0); + } #endif layered_window = true; } else { @@ -2747,13 +2654,16 @@ void OS_OSX::set_window_per_pixel_transparency_enabled(bool p_enabled) { [window_object setOpaque:YES]; [window_object setHasShadow:YES]; #if defined(OPENGL_ENABLED) - GLint opacity = 1; - [context setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity]; + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->set_opacity(1); + } #endif layered_window = false; } #if defined(OPENGL_ENABLED) - [context update]; + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->update(); + } #endif NSRect frame = [window_object frame]; [window_object setFrame:NSMakeRect(frame.origin.x, frame.origin.y, 1, 1) display:YES]; @@ -3073,11 +2983,20 @@ Error OS_OSX::move_to_trash(const String &p_path) { } void OS_OSX::_set_use_vsync(bool p_enable) { + // FIXME: Commented out during rebase of vulkan branch on master. + /* CGLContextObj ctx = CGLGetCurrentContext(); if (ctx) { GLint swapInterval = p_enable ? 1 : 0; CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval); } + */ +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + if (context_gles2) + context_gles2->set_use_vsync(p_enable); + } +#endif } OS_OSX *OS_OSX::singleton = NULL; diff --git a/platform/windows/SCsub b/platform/windows/SCsub index cde8c3d4801..6f014600250 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -13,14 +13,11 @@ common_win = [ "key_mapping_windows.cpp", "joypad_windows.cpp", "power_windows.cpp", - "windows_terminal_logger.cpp" + "windows_terminal_logger.cpp", + "vulkan_context_win.cpp", + "context_gl_windows.cpp" ] -if (env["renderer"] == "vulkan"): - common_win += ["vulkan_context_win.cpp"] -else: - common_win += ["context_gl_windows.cpp"] - res_file = 'godot_res.rc' res_target = "godot_res" + env["OBJSUFFIX"] res_obj = env.RES(res_target, res_file) diff --git a/platform/windows/detect.py b/platform/windows/detect.py index a4873ac24e5..0b65565a371 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -224,16 +224,15 @@ def configure_msvc(env, manual_msvc_config): 'shell32', 'advapi32', 'dinput8', 'dxguid', 'imm32', 'bcrypt', 'Avrt', 'dwmapi'] - if (env["renderer"] == "vulkan"): - env.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"]) - env.AppendUnique(CPPDEFINES = ['VULKAN_ENABLED']) - if not env["builtin_vulkan_loader"]: - LIBS += ['vulkan'] - else: - LIBS += ['cfgmgr32'] + env.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"]) + env.AppendUnique(CPPDEFINES = ['VULKAN_ENABLED']) + if not env["builtin_vulkan_loader"]: + LIBS += ['vulkan'] else: - env.AppendUnique(CPPDEFINES = ['OPENGL_ENABLED']) - LIBS += ['opengl32'] + LIBS += ['cfgmgr32'] + + #env.AppendUnique(CPPDEFINES = ['OPENGL_ENABLED']) + LIBS += ['opengl32'] env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in LIBS]) @@ -362,16 +361,16 @@ def configure_mingw(env): env.Append(CPPDEFINES=[('WINVER', env['target_win_version']), ('_WIN32_WINNT', env['target_win_version'])]) env.Append(LIBS=['mingw32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'imm32', 'bcrypt', 'avrt', 'uuid', 'dwmapi']) - if (env["renderer"] == "vulkan"): - env.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"]) - env.Append(CPPDEFINES=['VULKAN_ENABLED']) - if not env["builtin_vulkan_loader"]: - env.Append(LIBS=['vulkan']) - else: - env.Append(LIBS=['cfgmgr32']) + env.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"]) + env.Append(CPPDEFINES=['VULKAN_ENABLED']) + if not env["builtin_vulkan_loader"]: + env.Append(LIBS=['vulkan']) else: - env.Append(CPPDEFINES=['OPENGL_ENABLED']) - env.Append(LIBS=['opengl32']) + env.Append(LIBS=['cfgmgr32']) + + ## TODO !!! Reenable when OpenGLES Rendering Device is implemented !!! + #env.Append(CPPDEFINES=['OPENGL_ENABLED']) + env.Append(LIBS=['opengl32']) env.Append(CPPDEFINES=['MINGW_ENABLED', ('MINGW_HAS_SECURE_API', 1)]) diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 1f2fbd3f4fd..40ced686c8e 100755 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -38,10 +38,10 @@ #if defined(OPENGL_ENABLED) #include "drivers/gles2/rasterizer_gles2.h" -#include "drivers/gles3/rasterizer_gles3.h" #endif + #if defined(VULKAN_ENABLED) -#include "servers/visual/rasterizer/rasterizer_rd.h" +#include "servers/visual/rasterizer_rd/rasterizer_rd.h" #endif #include "drivers/windows/dir_access_windows.h" @@ -901,7 +901,9 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) set_window_size(Size2(video_mode.width, video_mode.height)); } #if defined(VULKAN_ENABLED) - context_vulkan->window_resize(0, video_mode.width, video_mode.height); + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + context_vulkan->window_resize(0, video_mode.width, video_mode.height); + } #endif } @@ -1426,91 +1428,61 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int SetWindowPos(hWnd, video_mode.always_on_top ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } -#if defined(OPENGL_ENABLED) - - bool gles3_context = true; - if (p_video_driver == VIDEO_DRIVER_GLES2) { - gles3_context = false; - } - - bool editor = Engine::get_singleton()->is_editor_hint(); - bool gl_initialization_error = false; - - gl_context = NULL; - while (!gl_context) { - gl_context = memnew(ContextGL_Windows(hWnd, gles3_context)); - - if (gl_context->initialize() != OK) { - memdelete(gl_context); - gl_context = NULL; - - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2") || editor) { - if (p_video_driver == VIDEO_DRIVER_GLES2) { - gl_initialization_error = true; - break; - } - - p_video_driver = VIDEO_DRIVER_GLES2; - gles3_context = false; - } else { - gl_initialization_error = true; - break; - } - } - } - - while (true) { - if (gles3_context) { - if (RasterizerGLES3::is_viable() == OK) { - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - break; - } else { - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2") || editor) { - p_video_driver = VIDEO_DRIVER_GLES2; - gles3_context = false; - continue; - } else { - gl_initialization_error = true; - break; - } - } - } else { - if (RasterizerGLES2::is_viable() == OK) { - RasterizerGLES2::register_config(); - RasterizerGLES2::make_current(); - break; - } else { - gl_initialization_error = true; - break; - } - } - } - - if (gl_initialization_error) { - OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n" - "Please update your drivers or if you have a very old or integrated GPU upgrade it.", - "Unable to initialize Video driver"); - return ERR_UNAVAILABLE; - } - + //!!!!!!!!!!!!!!!!!!!!!!!!!! + //TODO - do Vulkan and GLES2 support checks, driver selection and fallback video_driver_index = p_video_driver; + print_verbose("Driver: " + String(get_video_driver_name(video_driver_index)) + " [" + itos(video_driver_index) + "]"); + //!!!!!!!!!!!!!!!!!!!!!!!!!! - gl_context->set_use_vsync(video_mode.use_vsync); - set_vsync_via_compositor(video_mode.vsync_via_compositor); + // Init context and rendering device +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + + context_gles2 = memnew(ContextGL_Windows(hWnd, false)); + + if (context_gles2->initialize() != OK) { + memdelete(context_gles2); + context_gles2 = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } + + context_gles2->set_use_vsync(video_mode.use_vsync); + set_vsync_via_compositor(video_mode.vsync_via_compositor); + + if (RasterizerGLES2::is_viable() == OK) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + } else { + memdelete(context_gles2); + context_gles2 = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } + + } #endif #if defined(VULKAN_ENABLED) - video_driver_index = VIDEO_DRIVER_VULKAN; + if (video_driver_index == VIDEO_DRIVER_VULKAN) { - context_vulkan = memnew(VulkanContextWindows); - context_vulkan->initialize(); - context_vulkan->window_create(hWnd, hInstance, get_video_mode().width, get_video_mode().height); + context_vulkan = memnew(VulkanContextWindows); + if (context_vulkan->initialize() != OK) { + memdelete(context_vulkan); + context_vulkan = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } + if (context_vulkan->window_create(hWnd, hInstance, get_video_mode().width, get_video_mode().height) == -1) { + memdelete(context_vulkan); + context_vulkan = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } - //temporary - rendering_device = memnew(RenderingDeviceVulkan); - rendering_device->initialize(context_vulkan); - RasterizerRD::make_current(); + //temporary + rendering_device_vulkan = memnew(RenderingDeviceVulkan); + rendering_device_vulkan->initialize(context_vulkan); + + RasterizerRD::make_current(); + } #endif + visual_server = memnew(VisualServerRaster); if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); @@ -1681,16 +1653,26 @@ void OS_Windows::finalize() { cursors_cache.clear(); visual_server->finish(); memdelete(visual_server); -#ifdef OPENGL_ENABLED - if (gl_context) - memdelete(gl_context); + +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + + if (context_gles2) + memdelete(context_gles2); + + } #endif - #if defined(VULKAN_ENABLED) - rendering_device->finalize(); - memdelete(rendering_device); + if (video_driver_index == VIDEO_DRIVER_VULKAN) { - memdelete(context_vulkan); + if (rendering_device_vulkan) { + rendering_device_vulkan->finalize(); + memdelete(rendering_device_vulkan); + } + + if (context_vulkan) + memdelete(context_vulkan); + } #endif if (user_proc) { @@ -1992,9 +1974,10 @@ void OS_Windows::set_window_size(const Size2 p_size) { video_mode.width = w; video_mode.height = h; - #if defined(VULKAN_ENABLED) - context_vulkan->window_resize(0, video_mode.width, video_mode.height); + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + context_vulkan->window_resize(0, video_mode.width, video_mode.height); + } #endif if (video_mode.fullscreen) { @@ -3154,22 +3137,30 @@ OS::LatinKeyboardVariant OS_Windows::get_latin_keyboard_variant() const { void OS_Windows::release_rendering_thread() { #if defined(OPENGL_ENABLED) - gl_context->release_current(); + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->release_current(); + } #endif } void OS_Windows::make_rendering_thread() { #if defined(OPENGL_ENABLED) - gl_context->make_current(); + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->make_current(); + } #endif } void OS_Windows::swap_buffers() { #if defined(OPENGL_ENABLED) - gl_context->swap_buffers(); + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->swap_buffers(); + } #endif #if defined(VULKAN_ENABLED) - context_vulkan->swap_buffers(); + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + context_vulkan->swap_buffers(); + } #endif } @@ -3338,18 +3329,12 @@ String OS_Windows::get_joy_guid(int p_device) const { void OS_Windows::_set_use_vsync(bool p_enable) { #if defined(OPENGL_ENABLED) - if (gl_context) - gl_context->set_use_vsync(p_enable); + if (video_driver_index == VIDEO_DRIVER_GLES2) { + if (context_gles2) + context_gles2->set_use_vsync(p_enable); + } #endif } -/* -bool OS_Windows::is_vsync_enabled() const { - - if (gl_context) - return gl_context->is_using_vsync(); - - return true; -}*/ OS::PowerState OS_Windows::get_power_state() { return power_manager->get_power_state(); diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 64c7ed56dcf..89b67f8d918 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -178,13 +178,14 @@ class OS_Windows : public OS { bool outside; int old_x, old_y; Point2i center; + #if defined(OPENGL_ENABLED) - ContextGL_Windows *gl_context; + ContextGL_Windows *context_gles2; #endif #if defined(VULKAN_ENABLED) VulkanContextWindows *context_vulkan; - RenderingDeviceVulkan *rendering_device; + RenderingDeviceVulkan *rendering_device_vulkan; #endif VisualServer *visual_server; diff --git a/platform/x11/SCsub b/platform/x11/SCsub index 09e283b6343..9027c244bef 100644 --- a/platform/x11/SCsub +++ b/platform/x11/SCsub @@ -6,7 +6,7 @@ from platform_methods import run_in_subprocess import platform_x11_builders common_x11 = [ - #"context_gl_x11.cpp", + "context_gl_x11.cpp", "vulkan_context_x11.cpp", "crash_handler_x11.cpp", "os_x11.cpp", diff --git a/platform/x11/detect.py b/platform/x11/detect.py index eee439ceb4e..ed48fbb74a0 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -320,14 +320,13 @@ def configure(env): env.Prepend(CPPPATH=['#platform/x11']) env.Append(CPPDEFINES=['X11_ENABLED', 'UNIX_ENABLED']) - if (env["renderer"] == "vulkan"): - env.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"]) - env.Append(CPPDEFINES=['VULKAN_ENABLED']) - if not env["builtin_vulkan_loader"]: - env.Append(LIBS=['vulkan']) - else: - env.Append(CPPDEFINES=['OPENGL_ENABLED']) - env.Append(LIBS=['GL']) + env.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"]) + env.Append(CPPDEFINES=['VULKAN_ENABLED']) + if not env["builtin_vulkan_loader"]: + env.Append(LIBS=['vulkan']) + + #env.Append(CPPDEFINES=['OPENGL_ENABLED']) + env.Append(LIBS=['GL']) env.Append(LIBS=['pthread']) diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 5776a450426..e19e808df12 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -33,11 +33,17 @@ #include "core/os/dir_access.h" #include "core/print_string.h" -//#include "drivers/gles2/rasterizer_gles2.h" -//#include "drivers/gles3/rasterizer_gles3.h" #include "errno.h" #include "key_mapping_x11.h" + +#if defined(OPENGL_ENABLED) +#include "drivers/gles2/rasterizer_gles2.h" +#endif + +#if defined(VULKAN_ENABLED) #include "servers/visual/rasterizer_rd/rasterizer_rd.h" +#endif + #include "servers/visual/visual_server_raster.h" #include "servers/visual/visual_server_wrap_mt.h" @@ -103,15 +109,7 @@ void OS_X11::initialize_core() { int OS_X11::get_current_video_driver() const { return video_driver_index; } -#if 0 -static RID test_index_array; -static RID test_vertex_array; -static RID test_uniform_set; -static RID test_pipeline; -static RID test_framebuffer_pipeline; -static RID test_framebuffer_uniform_set; -static RID test_framebuffer; -#endif + Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { long im_event_mask = 0; @@ -239,138 +237,14 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a XFree(imvalret); } -/* - char* windowid = getenv("GODOT_WINDOWID"); - if (windowid) { - - //freopen("/home/punto/stdout", "w", stdout); - //reopen("/home/punto/stderr", "w", stderr); - x11_window = atol(windowid); - - XWindowAttributes xwa; - XGetWindowAttributes(x11_display,x11_window,&xwa); - - current_videomode.width = xwa.width; - current_videomode.height = xwa.height; - }; - */ - -// maybe contextgl wants to be in charge of creating the window -#if defined(OPENGL_ENABLED) - if (getenv("DRI_PRIME") == NULL) { - int use_prime = -1; - - if (getenv("PRIMUS_DISPLAY") || - getenv("PRIMUS_libGLd") || - getenv("PRIMUS_libGLa") || - getenv("PRIMUS_libGL") || - getenv("PRIMUS_LOAD_GLOBAL") || - getenv("BUMBLEBEE_SOCKET")) { - - print_verbose("Optirun/primusrun detected. Skipping GPU detection"); - use_prime = 0; - } - - if (getenv("LD_LIBRARY_PATH")) { - String ld_library_path(getenv("LD_LIBRARY_PATH")); - Vector libraries = ld_library_path.split(":"); - - for (int i = 0; i < libraries.size(); ++i) { - if (FileAccess::exists(libraries[i] + "/libGL.so.1") || - FileAccess::exists(libraries[i] + "/libGL.so")) { - - print_verbose("Custom libGL override detected. Skipping GPU detection"); - use_prime = 0; - } - } - } - - if (use_prime == -1) { - print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic."); - use_prime = detect_prime(); - } - - if (use_prime) { - print_line("Found discrete GPU, setting DRI_PRIME=1 to use it."); - print_line("Note: Set DRI_PRIME=0 in the environment to disable Godot from using the discrete GPU."); - setenv("DRI_PRIME", "1", 1); - } - } - - ContextGL_X11::ContextType opengl_api_type = ContextGL_X11::GLES_3_0_COMPATIBLE; - - if (p_video_driver == VIDEO_DRIVER_GLES2) { - opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE; - } - - bool editor = Engine::get_singleton()->is_editor_hint(); - bool gl_initialization_error = false; - - context_gl = NULL; - while (!context_gl) { - context_gl = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, opengl_api_type)); - - if (context_gl->initialize() != OK) { - memdelete(context_gl); - context_gl = NULL; - - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2") || editor) { - if (p_video_driver == VIDEO_DRIVER_GLES2) { - gl_initialization_error = true; - break; - } - - p_video_driver = VIDEO_DRIVER_GLES2; - opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE; - } else { - gl_initialization_error = true; - break; - } - } - } - - while (true) { - if (opengl_api_type == ContextGL_X11::GLES_3_0_COMPATIBLE) { - if (RasterizerGLES3::is_viable() == OK) { - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - break; - } else { - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2") || editor) { - p_video_driver = VIDEO_DRIVER_GLES2; - opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE; - continue; - } else { - gl_initialization_error = true; - break; - } - } - } - - if (opengl_api_type == ContextGL_X11::GLES_2_0_COMPATIBLE) { - if (RasterizerGLES2::is_viable() == OK) { - RasterizerGLES2::register_config(); - RasterizerGLES2::make_current(); - break; - } else { - gl_initialization_error = true; - break; - } - } - } - - if (gl_initialization_error) { - OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n" - "Please update your drivers or if you have a very old or integrated GPU upgrade it.", - "Unable to initialize Video driver"); - return ERR_UNAVAILABLE; - } - + //!!!!!!!!!!!!!!!!!!!!!!!!!! + //TODO - do Vulkan and GLES2 support checks, driver selection and fallback video_driver_index = p_video_driver; + print_verbose("Driver: " + String(get_video_driver_name(video_driver_index)) + " [" + itos(video_driver_index) + "]"); + //!!!!!!!!!!!!!!!!!!!!!!!!!! - context_gl->set_use_vsync(current_videomode.use_vsync); + //Create window -#else long visualMask = VisualScreenMask; int numberOfVisuals; XVisualInfo vInfoTemplate = {}; @@ -384,11 +258,7 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a windowAttributes.background_pixel = 0xFFFFFFFF; windowAttributes.border_pixel = 0; windowAttributes.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask | ExposureMask; - /* - window = XCreateWindow(demo->display, RootWindow(display, vInfoTemplate.screen), 0, 0, demo->width, - demo->height, 0, visualInfo->depth, InputOutput, visualInfo->visual, - CWBackPixel | CWBorderPixel | CWEventMask | CWColormap, &windowAttributes); - */ + unsigned long valuemask = CWBorderPixel | CWColormap | CWEventMask; x11_window = XCreateWindow(x11_display, RootWindow(x11_display, visualInfo->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, visualInfo->depth, InputOutput, visualInfo->visual, valuemask, &windowAttributes); @@ -401,261 +271,92 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a XFree(visualInfo); - context_vulkan = memnew(VulkanContextX11); - context_vulkan->initialize(); - context_vulkan->window_create(x11_window, x11_display, get_video_mode().width, get_video_mode().height); + // Init context and rendering device +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + if (getenv("DRI_PRIME") == NULL) { + int use_prime = -1; - //temporary - rendering_device = memnew(RenderingDeviceVulkan); - rendering_device->initialize(context_vulkan); - RasterizerRD::make_current(); + if (getenv("PRIMUS_DISPLAY") || + getenv("PRIMUS_libGLd") || + getenv("PRIMUS_libGLa") || + getenv("PRIMUS_libGL") || + getenv("PRIMUS_LOAD_GLOBAL") || + getenv("BUMBLEBEE_SOCKET")) { - // test shader -#if 0 - //test code, remains for reference, ask before removing - RID shader; - { - RenderingDevice::ShaderStageSource vert; - vert.shader_stage = RenderingDevice::SHADER_STAGE_VERTEX; - vert.shader_source = "#version 450\n" - "layout(location = 0) in vec4 vertex_pos;\n" - "layout(location = 1) in vec2 uv_pos;\n" - "layout(location = 0) out vec2 uv_interp;\n" - "void main() { gl_Position = vertex_pos; uv_interp=uv_pos;\n }"; - //"void main() { if (gl_VertexIndex==0) gl_Position=vec4(-0.8,-0.8,0.0,1.0); if (gl_VertexIndex==1) gl_Position=vec4(-0.8,-0.2,0.0,1.0); if (gl_VertexIndex==2) gl_Position=vec4(-0.2,-0.2,0.0,1.0); if (gl_VertexIndex==3) gl_Position=vec4(-0.2,-0.8,0.0,1.0);\n }"; + print_verbose("Optirun/primusrun detected. Skipping GPU detection"); + use_prime = 0; + } - RenderingDevice::ShaderStageSource frag; - frag.shader_stage = RenderingDevice::SHADER_STAGE_FRAGMENT; - frag.shader_source = "#version 450\n" - "layout (location = 0) in vec2 uv_interp;\n" - "layout (location = 0) out vec4 uFragColor;\n" - "layout (binding = 0) uniform sampler2D t;\n" - "layout (push_constant, binding=1) uniform ColorMultiplier { vec4 color_mult; } color_multiplier;\n" - "void main() { uFragColor=texture(t,uv_interp) * color_multiplier.color_mult; }\n"; + if (getenv("LD_LIBRARY_PATH")) { + String ld_library_path(getenv("LD_LIBRARY_PATH")); + Vector libraries = ld_library_path.split(":"); - Vector source; - source.push_back(vert); - source.push_back(frag); - String error; - shader = rendering_device->shader_create_from_source(source, &error); - if (!shader.is_valid()) { - print_line("failed compilation: " + error); + for (int i = 0; i < libraries.size(); ++i) { + if (FileAccess::exists(libraries[i] + "/libGL.so.1") || + FileAccess::exists(libraries[i] + "/libGL.so")) { + + print_verbose("Custom libGL override detected. Skipping GPU detection"); + use_prime = 0; + } + } + } + + if (use_prime == -1) { + print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic."); + use_prime = detect_prime(); + } + + if (use_prime) { + print_line("Found discrete GPU, setting DRI_PRIME=1 to use it."); + print_line("Note: Set DRI_PRIME=0 in the environment to disable Godot from using the discrete GPU."); + setenv("DRI_PRIME", "1", 1); + } + } + + ContextGL_X11::ContextType opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE; + + context_gles2 = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, opengl_api_type)); + + if (context_gles2->initialize() != OK) { + memdelete(context_gles2); + context_gles2 = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } + + context_gles2->set_use_vsync(current_videomode.use_vsync); + + if (RasterizerGLES2::is_viable() == OK) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); } else { - print_line("compilation success"); + memdelete(context_gles2); + context_gles2 = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); } } - - RenderingDevice::VertexFormatID vertex_desc; - { - - PoolVector pv; - pv.resize(24 * 4); - { - PoolVector::Write w = pv.write(); - float *p32 = (float *)w.ptr(); - p32[0] = -0.8; - p32[1] = -0.8; - p32[2] = 0.0; - p32[3] = 1.0; - - p32[4] = 0.0; - p32[5] = 0.0; - - p32[6] = -0.8; - p32[7] = -0.2; - p32[8] = 0.0; - p32[9] = 1.0; - - p32[10] = 0.0; - p32[11] = 1.0; - - p32[12] = -0.2; - p32[13] = -0.2; - p32[14] = 0.0; - p32[15] = 1.0; - - p32[16] = 1.0; - p32[17] = 1.0; - - p32[18] = -0.2; - p32[19] = -0.8; - p32[20] = 0.0; - p32[21] = 1.0; - - p32[22] = 1.0; - p32[23] = 0.0; - } - - RID vertex_buffer = rendering_device->vertex_buffer_create(pv.size(), pv); - Vector vdarr; - RenderingDevice::VertexDescription vd; - vd.format = RenderingDevice::DATA_FORMAT_R32G32B32A32_SFLOAT; - vd.stride = 4 * 6; //vertex/uv - vd.offset = 0; - vd.location = 0; - vdarr.push_back(vd); - vd.format = RenderingDevice::DATA_FORMAT_R32G32_SFLOAT; - vd.stride = 4 * 6; //vertex/uv - vd.offset = 4 * 4; //offset to UV - vd.location = 1; - vdarr.push_back(vd); - - vertex_desc = rendering_device->vertex_format_create(vdarr); - - Vector buffers; - buffers.push_back(vertex_buffer); - buffers.push_back(vertex_buffer); - - test_vertex_array = rendering_device->vertex_array_create(4, vertex_desc, buffers); - } - - RID test_framebuffer_tex_id; - - { - RenderingDevice::TextureFormat tex_format; - tex_format.format = RenderingDevice::DATA_FORMAT_R8G8B8A8_UNORM; //RenderingDevice::DATA_FORMAT_A8B8G8R8_UNORM_PACK32; - tex_format.width = 256; - tex_format.height = 256; - tex_format.mipmaps = 1; - tex_format.type = RenderingDevice::TEXTURE_TYPE_2D; - tex_format.usage_bits = RenderingDevice::TEXTURE_USAGE_SAMPLING_BIT | RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; - - test_framebuffer_tex_id = rendering_device->texture_create(tex_format, RenderingDevice::TextureView()); - - Vector ids; - ids.push_back(test_framebuffer_tex_id); - - test_framebuffer = rendering_device->framebuffer_create(ids); - } - - test_pipeline = rendering_device->render_pipeline_create(shader, rendering_device->framebuffer_get_format(test_framebuffer), vertex_desc, RenderingDevice::RENDER_PRIMITIVE_TRIANGLES, RenderingDevice::PipelineRasterizationState(), RenderingDevice::PipelineMultisampleState(), RenderingDevice::PipelineDepthStencilState(), RenderingDevice::PipelineColorBlendState::create_disabled()); - - { - - Ref img; - img.instance(); - Error terr = img->load("../logo.png"); - if (terr != OK) { - print_line("Cant load logo?"); - } - - img->convert(Image::FORMAT_RGBA8); - - RenderingDevice::TextureFormat tex_format; - tex_format.format = RenderingDevice::DATA_FORMAT_R8G8B8A8_UNORM; //RenderingDevice::DATA_FORMAT_A8B8G8R8_UNORM_PACK32; - tex_format.width = img->get_width(); - tex_format.height = img->get_height(); - print_line("imgsize: " + Vector2(img->get_width(), img->get_height())); - tex_format.mipmaps = 1; - tex_format.type = RenderingDevice::TEXTURE_TYPE_2D; - tex_format.usage_bits = RenderingDevice::TEXTURE_USAGE_SAMPLING_BIT | RenderingDevice::TEXTURE_USAGE_CAN_UPDATE_BIT; - - Vector > initial_data; - initial_data.push_back(img->get_data()); - - RID tex_id = rendering_device->texture_create(tex_format, RenderingDevice::TextureView(), initial_data); - RID sampler = rendering_device->sampler_create(RenderingDevice::SamplerState()); - - Vector uniform_description; - - RenderingDevice::Uniform u; - u.type = RenderingDevice::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; - u.binding = 0; - u.ids.push_back(sampler); - u.ids.push_back(tex_id); - - uniform_description.push_back(u); - - test_uniform_set = rendering_device->uniform_set_create(uniform_description, shader, 0); - } - - { - PoolVector pv; - pv.resize(6 * 4); - { - PoolVector::Write w = pv.write(); - int *p32 = (int *)w.ptr(); - p32[0] = 0; - p32[1] = 1; - p32[2] = 2; - p32[3] = 0; - p32[4] = 2; - p32[5] = 3; - } - RID index_buffer = rendering_device->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, pv); - test_index_array = rendering_device->index_array_create(index_buffer, 0, 6); - } - - { - - RID sampler = rendering_device->sampler_create(RenderingDevice::SamplerState()); - - Vector uniform_description; - - RenderingDevice::Uniform u; - u.type = RenderingDevice::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; - u.binding = 0; - u.ids.push_back(sampler); - u.ids.push_back(test_framebuffer_tex_id); - - uniform_description.push_back(u); - - test_framebuffer_uniform_set = rendering_device->uniform_set_create(uniform_description, shader, 0); - test_framebuffer_pipeline = rendering_device->render_pipeline_create(shader, rendering_device->screen_get_framebuffer_format(), vertex_desc, RenderingDevice::RENDER_PRIMITIVE_TRIANGLES, RenderingDevice::PipelineRasterizationState(), RenderingDevice::PipelineMultisampleState(), RenderingDevice::PipelineDepthStencilState(), RenderingDevice::PipelineColorBlendState::create_disabled()); - } - -#endif -#if 0 - //test code, remains for reference, ask before removing - Vector source; - RenderingDevice::ShaderStageSource frag; - frag.shader_stage = RenderingDevice::SHADER_STAGE_FRAGMENT; - frag.shader_source = "" - "#version 450\n" - "#extension GL_ARB_separate_shader_objects : enable\n" - "#extension GL_ARB_shading_language_420pack : enable\n" - "layout (set =2, binding = 3) uniform sampler2D sampie;\n" - "layout (set =2, binding = 4) uniform texture2D texie;\n" - "layout (set =2, binding = 5) uniform sampler sampieonly;\n" - "layout (set =2, binding = 6) uniform sampler2D sampiearr[2];\n" - "layout (set =2, binding = 7) uniform texture2D texiearr[2];\n" - "layout (set =2, binding = 8) uniform sampler sampieonlyarr[2];\n" - "layout (set =2, binding = 9) uniform samplerBuffer sabufsa;\n" - "layout (set =2, binding = 9) uniform textureBuffer texbufsa;\n" - "layout (set=3,binding=1,rgba32f) uniform image2D img1;\n" - "layout(std140, set=1,binding = 0) uniform buf {\n" - " mat4 MVP;\n" - " vec4 position[12*3];\n" - " vec4 attr[12*3];\n" - "} ubuf;\n" - "layout(std140, set=1,binding = 1) buffer popis {\n" - " int popitos;\n" - "} popibuf;\n" - "layout (location = 0) out vec4 uFragColor;\n" - " \n" - "const vec3 lightDir= vec3(0.424, 0.566, 0.707);\n" - "\n" - "void main() {\n" - " uFragColor = texture(sampie, vec2(ubuf.attr[0].x));\n" - " uFragColor+= texture(sampler2D(texie,sampieonly), vec2(ubuf.attr[0].x));\n" - " uFragColor+= texture(sampiearr[1], vec2(ubuf.attr[0].x));\n" - " uFragColor+= texture(sampler2D(texiearr[1],sampieonlyarr[1]), vec2(ubuf.attr[0].x));\n" - " uFragColor+= texelFetch(sabufsa,0);\n" - " uFragColor+= texelFetch(samplerBuffer(texbufsa,sampieonly),0);\n" - " uFragColor+= texelFetch(texbufsa,0);\n" - " uFragColor.xy+= imageSize(img1);\n" - " uFragColor.x+= float(popibuf.popitos);\n" - "}\n"; - source.push_back(frag); - String error; - RID shader = rendering_device->shader_create_from_source(source, &error); - if (shader == RenderingDevice::INVALID_ID) { - print_line("failed compilation: " + error); - } else { - print_line("compilation success"); - } #endif +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + context_vulkan = memnew(VulkanContextX11); + if (context_vulkan->initialize() != OK) { + memdelete(context_vulkan); + context_vulkan = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } + if (context_vulkan->window_create(x11_window, x11_display, get_video_mode().width, get_video_mode().height) == -1) { + memdelete(context_vulkan); + context_vulkan = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } + + //temporary + rendering_device_vulkan = memnew(RenderingDeviceVulkan); + rendering_device_vulkan->initialize(context_vulkan); + + RasterizerRD::make_current(); + } #endif visual_server = memnew(VisualServerRaster); @@ -1164,24 +865,35 @@ void OS_X11::finalize() { visual_server->finish(); memdelete(visual_server); - rendering_device->finalize(); - memdelete(rendering_device); - - memdelete(context_vulkan); - - //memdelete(rasterizer); - memdelete(power_manager); +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + + if (context_gles2) + memdelete(context_gles2); + + } +#endif +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + + if (rendering_device_vulkan) { + rendering_device_vulkan->finalize(); + memdelete(rendering_device_vulkan); + } + + if (context_vulkan) + memdelete(context_vulkan); + } +#endif + if (xrandr_handle) dlclose(xrandr_handle); XUnmapWindow(x11_display, x11_window); XDestroyWindow(x11_display, x11_window); -#if defined(OPENGL_ENABLED) - memdelete(context_gl); -#endif for (int i = 0; i < CURSOR_MAX; i++) { if (cursors[i] != None) XFreeCursor(x11_display, cursors[i]); @@ -2423,7 +2135,12 @@ void OS_X11::_window_changed(XEvent *event) { current_videomode.width = event->xconfigure.width; current_videomode.height = event->xconfigure.height; - context_vulkan->window_resize(0, current_videomode.width, current_videomode.height); + +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + context_vulkan->window_resize(0, current_videomode.width, current_videomode.height); + } +#endif } void OS_X11::process_xevents() { @@ -3408,48 +3125,32 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c } void OS_X11::release_rendering_thread() { - #if defined(OPENGL_ENABLED) - context_gl->release_current(); + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->release_current(); + } #endif } void OS_X11::make_rendering_thread() { - #if defined(OPENGL_ENABLED) - context_gl->make_current(); + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->make_current(); + } #endif } void OS_X11::swap_buffers() { - #if defined(OPENGL_ENABLED) - context_gl->swap_buffers(); + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->swap_buffers(); + } #endif -#if 0 - Vector clear; - float color[4] = { 1, 0, 1, 1 }; - clear.push_back(Color(0.5, 0.8, 0.2)); - RenderingDevice::DrawListID cmd_list = rendering_device->draw_list_begin(test_framebuffer, RenderingDevice::INITIAL_ACTION_CLEAR, RenderingDevice::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH, clear); - rendering_device->draw_list_bind_render_pipeline(cmd_list, test_pipeline); - rendering_device->draw_list_bind_index_array(cmd_list, test_index_array); - rendering_device->draw_list_bind_vertex_array(cmd_list, test_vertex_array); - rendering_device->draw_list_bind_uniform_set(cmd_list, test_uniform_set, 0); - rendering_device->draw_list_set_push_constant(cmd_list, color, 4 * 4); - rendering_device->draw_list_draw(cmd_list, true); - rendering_device->draw_list_end(); - - cmd_list = rendering_device->draw_list_begin_for_screen(); - rendering_device->draw_list_bind_render_pipeline(cmd_list, test_framebuffer_pipeline); - rendering_device->draw_list_bind_index_array(cmd_list, test_index_array); - rendering_device->draw_list_bind_vertex_array(cmd_list, test_vertex_array); - rendering_device->draw_list_bind_uniform_set(cmd_list, test_framebuffer_uniform_set, 0); - rendering_device->draw_list_set_push_constant(cmd_list, color, 4 * 4); - rendering_device->draw_list_draw(cmd_list, true); - rendering_device->draw_list_end(); +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + context_vulkan->swap_buffers(); + } #endif - - context_vulkan->swap_buffers(); } void OS_X11::alert(const String &p_alert, const String &p_title) { @@ -3637,19 +3338,13 @@ String OS_X11::get_joy_guid(int p_device) const { void OS_X11::_set_use_vsync(bool p_enable) { #if defined(OPENGL_ENABLED) - if (context_gl) - context_gl->set_use_vsync(p_enable); + if (video_driver_index == VIDEO_DRIVER_GLES2) { + if (context_gles2) + context_gles2->set_use_vsync(p_enable); + } #endif } -/* -bool OS_X11::is_vsync_enabled() const { - if (context_gl) - return context_gl->is_using_vsync(); - - return true; -} -*/ void OS_X11::set_context(int p_context) { XClassHint *classHint = XAllocClassHint(); diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 5999e2840e8..fd8a9817636 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -31,7 +31,6 @@ #ifndef OS_X11_H #define OS_X11_H -//#include "context_gl_x11.h" #include "core/os/input.h" #include "crash_handler_x11.h" #include "drivers/alsa/audio_driver_alsa.h" @@ -44,9 +43,15 @@ #include "servers/audio_server.h" #include "servers/visual/rasterizer.h" #include "servers/visual_server.h" -//#include "servers/visual/visual_server_wrap_mt.h" + +#if defined(OPENGL_ENABLED) +#include "context_gl_x11.h" +#endif + +#if defined(VULKAN_ENABLED) #include "drivers/vulkan/rendering_device_vulkan.h" #include "platform/x11/vulkan_context_x11.h" +#endif #include #include @@ -94,11 +99,11 @@ class OS_X11 : public OS_Unix { int xdnd_version; #if defined(OPENGL_ENABLED) - ContextGL_X11 *context_gl; + ContextGL_X11 *context_gles2; #endif #if defined(VULKAN_ENABLED) VulkanContextX11 *context_vulkan; - RenderingDeviceVulkan *rendering_device; + RenderingDeviceVulkan *rendering_device_vulkan; #endif //Rasterizer *rasterizer; diff --git a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp index 11bc423804b..35f75ecd9d9 100644 --- a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp @@ -2094,6 +2094,10 @@ EffectsRD *RasterizerStorageRD::get_effects() { RasterizerStorageRD::RasterizerStorageRD() { + for (int i = 0; i < SHADER_TYPE_MAX; i++) { + shader_data_request_func[i] = NULL; + } + material_update_list = NULL; { //create default textures