Add runtime GLES2 / Vulkan context selection.

This commit is contained in:
bruvzg 2019-07-12 16:18:30 +03:00
parent eb48be51db
commit b456bfad5c
21 changed files with 743 additions and 830 deletions

View file

@ -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('target', "Compilation target", 'debug', ('debug', 'release_debug', 'release')))
opts.Add(EnumVariable('optimize', "Optimization type", 'speed', ('speed', 'size'))) 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('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_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)) opts.Add(BoolVariable('use_precise_math_checks', 'Math checks use very precise epsilon (useful to debug the engine)', False))

View file

@ -689,13 +689,11 @@ int OS::get_video_driver_count() const {
const char *OS::get_video_driver_name(int p_driver) const { const char *OS::get_video_driver_name(int p_driver) const {
switch (p_driver) { switch (p_driver) {
case VIDEO_DRIVER_VULKAN:
return "Vulkan";
case VIDEO_DRIVER_GLES2: case VIDEO_DRIVER_GLES2:
return "GLES2"; return "GLES2";
case VIDEO_DRIVER_GLES3: case VIDEO_DRIVER_VULKAN:
default: default:
return "GLES3"; return "Vulkan";
} }
} }

View file

@ -181,9 +181,8 @@ public:
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const = 0; virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const = 0;
enum VideoDriver { enum VideoDriver {
VIDEO_DRIVER_GLES3,
VIDEO_DRIVER_GLES2,
VIDEO_DRIVER_VULKAN, VIDEO_DRIVER_VULKAN,
VIDEO_DRIVER_GLES2,
VIDEO_DRIVER_MAX, VIDEO_DRIVER_MAX,
}; };

View file

@ -4905,7 +4905,9 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin_for_screen(in
VkCommandBuffer command_buffer = frames[frame].draw_command_buffer; VkCommandBuffer command_buffer = frames[frame].draw_command_buffer;
draw_list = memnew(DrawList); draw_list = memnew(DrawList);
draw_list->command_buffer = command_buffer; draw_list->command_buffer = command_buffer;
#ifdef DEBUG_ENABLED
draw_list->validation.framebuffer_format = screen_get_framebuffer_format(); draw_list->validation.framebuffer_format = screen_get_framebuffer_format();
#endif
draw_list_count = 0; draw_list_count = 0;
draw_list_split = false; draw_list_split = false;
@ -5101,7 +5103,9 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
draw_list = memnew(DrawList); draw_list = memnew(DrawList);
draw_list->command_buffer = command_buffer; draw_list->command_buffer = command_buffer;
#ifdef DEBUG_ENABLED
draw_list->validation.framebuffer_format = framebuffer->format_id; draw_list->validation.framebuffer_format = framebuffer->format_id;
#endif
draw_list_count = 0; draw_list_count = 0;
draw_list_split = false; 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; draw_list[i].command_buffer = command_buffer;
#ifdef DEBUG_ENABLED
draw_list[i].validation.framebuffer_format = framebuffer->format_id; draw_list[i].validation.framebuffer_format = framebuffer->format_id;
#endif
VkViewport viewport; VkViewport viewport;
viewport.x = viewport_offset.x; viewport.x = viewport_offset.x;
@ -5430,9 +5436,9 @@ void RenderingDeviceVulkan::draw_list_bind_vertex_array(DrawListID p_list, RID p
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
dl->validation.vertex_format = vertex_array->description; 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; dl->validation.vertex_max_instances_allowed = vertex_array->max_instances_allowed;
#endif #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()); 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) { 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; dl->state.index_array = p_index_array;
#ifdef DEBUG_ENABLED #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_max_index = index_array->max_index;
dl->validation.index_array_offset = index_array->offset;
#endif #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); 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); DrawList *dl = _get_draw_list_ptr(p_list);
ERR_FAIL_COND(!dl); ERR_FAIL_COND(!dl);
#ifdef DEBUG_ENABLED
ERR_FAIL_COND_MSG(!dl->validation.active, "Submitted Draw Lists can no longer be modified."); ERR_FAIL_COND_MSG(!dl->validation.active, "Submitted Draw Lists can no longer be modified.");
#endif
vkCmdSetLineWidth(dl->command_buffer, p_width); 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) + ")"); "This render pipeline requires (" + itos(dl->validation.pipeline_push_constant_size) + ") bytes of push constant data, supplied: (" + itos(p_data_size) + ")");
#endif #endif
vkCmdPushConstants(dl->command_buffer, dl->state.pipeline_layout, dl->state.pipeline_push_constant_stages, 0, p_data_size, p_data); 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; dl->validation.pipeline_push_constant_suppplied = true;
#endif
} }
void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances) { void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances) {

View file

@ -767,6 +767,17 @@ class RenderingDeviceVulkan : public RenderingDevice {
pipeline_push_constant_suppplied = false; pipeline_push_constant_suppplied = false;
} }
} validation; } 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 #endif
}; };

View file

@ -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); OS::get_singleton()->set_cmdline(execpath, main_args);
GLOBAL_DEF("rendering/quality/driver/driver_name", "GLES3"); 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, "GLES2,GLES3,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 == "") { if (video_driver == "") {
video_driver = GLOBAL_GET("rendering/quality/driver/driver_name"); video_driver = GLOBAL_GET("rendering/quality/driver/driver_name");
} }

View file

@ -13,11 +13,10 @@ files = [
'dir_access_osx.mm', 'dir_access_osx.mm',
'joypad_osx.cpp', 'joypad_osx.cpp',
'power_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) prog = env.add_program('#bin/godot', files)
if (env["debug_symbols"] == "full" or env["debug_symbols"] == "yes") and env["separate_debug_symbols"]: if (env["debug_symbols"] == "full" or env["debug_symbols"] == "yes") and env["separate_debug_symbols"]:

View file

@ -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 <AppKit/AppKit.h>
#include <ApplicationServices/ApplicationServices.h>
#include <CoreVideo/CoreVideo.h>
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

View file

@ -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

View file

@ -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(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']) env.Append(LIBS=['pthread', 'z'])
if (env["renderer"] == "vulkan"): env.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"])
env.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"]) env.Append(CPPDEFINES=['VULKAN_ENABLED'])
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.Append(CCFLAGS=['-mmacosx-version-min=10.11']) #env.Append(CPPDEFINES=['GLES_ENABLED', 'OPENGL_ENABLED'])
env.Append(LINKFLAGS=['-mmacosx-version-min=10.11'])
else:
env.Append(CPPDEFINES=['GLES_ENABLED'])
env.Append(LINKFLAGS=['-framework', 'OpenGL', '-framework', 'AGL'])
env.Append(CCFLAGS=['-mmacosx-version-min=10.9']) env.Append(LINKFLAGS=['-framework', 'Metal', '-framework', 'QuartzCore', '-framework', 'IOSurface'])
env.Append(LINKFLAGS=['-mmacosx-version-min=10.9']) 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'])

View file

@ -46,6 +46,10 @@
#include "servers/visual/visual_server_wrap_mt.h" #include "servers/visual/visual_server_wrap_mt.h"
#include "servers/visual_server.h" #include "servers/visual_server.h"
#if defined(OPENGL_ENABLED)
#include "context_gl_osx.h"
#endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
#include "drivers/vulkan/rendering_device_vulkan.h" #include "drivers/vulkan/rendering_device_vulkan.h"
#include "platform/osx/vulkan_context_osx.h" #include "platform/osx/vulkan_context_osx.h"
@ -110,14 +114,12 @@ public:
id cursor; id cursor;
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
void *framework; ContextGL_OSX *context_gles2;
NSOpenGLPixelFormat *pixelFormat;
NSOpenGLContext *context;
#endif #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
VulkanContextOSX *context_vulkan; VulkanContextOSX *context_vulkan;
RenderingDeviceVulkan *rendering_device; RenderingDeviceVulkan *rendering_device_vulkan;
#endif #endif
bool layered_window; bool layered_window;

View file

@ -37,10 +37,10 @@
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
#include "drivers/gles2/rasterizer_gles2.h" #include "drivers/gles2/rasterizer_gles2.h"
#include "drivers/gles3/rasterizer_gles3.h"
#endif #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
#include "servers/visual/rasterizer/rasterizer_rd.h" #include "servers/visual/rasterizer_rd/rasterizer_rd.h"
#endif #endif
#include "main/main.h" #include "main/main.h"
@ -271,29 +271,6 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) {
return NSTerminateCancel; 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 { - (void)showAbout:(id)sender {
if (OS_OSX::singleton->get_main_loop()) if (OS_OSX::singleton->get_main_loop())
OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_ABOUT); 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]; NSWindow *window = (NSWindow *)[notification object];
CGFloat newBackingScaleFactor = [window backingScaleFactor]; CGFloat newBackingScaleFactor = [window backingScaleFactor];
CGFloat oldBackingScaleFactor = [[[notification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue]; CGFloat oldBackingScaleFactor = [[[notification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue];
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
if (OS_OSX::singleton->is_hidpi_allowed()) { if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_GLES2) {
[OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:YES]; if (OS_OSX::singleton->is_hidpi_allowed()) {
} else { [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:YES];
[OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:NO]; } else {
[OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:NO];
}
} }
#endif #endif
@ -374,10 +354,12 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) {
} }
- (void)windowDidResize:(NSNotification *)notification { - (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 contentRect = [OS_OSX::singleton->window_view frame];
const NSRect fbRect = contentRect; 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; OS_OSX::singleton->window_size.height = fbRect.size.height * displayScale;
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
CALayer* layer = [OS_OSX::singleton->window_view layer]; if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_VULKAN) {
layer.contentsScale = OS_OSX::singleton->_display_scale(); CALayer* layer = [OS_OSX::singleton->window_view layer];
OS_OSX::singleton->context_vulkan->window_resize(0, OS_OSX::singleton->window_size.width, OS_OSX::singleton->window_size.height); 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 #endif
if (OS_OSX::singleton->main_loop) { if (OS_OSX::singleton->main_loop) {
@ -398,15 +382,6 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) {
Main::iteration(); 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 { - (void)windowDidMove:(NSNotification *)notification {
@ -414,17 +389,6 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) {
if (OS_OSX::singleton->get_main_loop()) { if (OS_OSX::singleton->get_main_loop()) {
OS_OSX::singleton->input->release_pressed_events(); 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 { - (void)windowDidBecomeKey:(NSNotification *)notification {
@ -489,21 +453,25 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) {
- (CALayer*)makeBackingLayer { - (CALayer*)makeBackingLayer {
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
CALayer* layer = [[CAMetalLayer class] layer]; if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_VULKAN) {
layer.contentsScale = OS_OSX::singleton->_display_scale(); CALayer* layer = [[CAMetalLayer class] layer];
return layer; layer.contentsScale = OS_OSX::singleton->_display_scale();
return layer;
}
#endif #endif
#if defined(OPENGL_ENABLED)
return [super makeBackingLayer]; return [super makeBackingLayer];
#endif
} }
- (void)updateLayer { - (void)updateLayer {
#if defined(OPENGL_ENABLED)
[OS_OSX::singleton->context update];
#endif
#if defined(VULKAN_ENABLED) #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 #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 // Register to be notified on displays arrangement changes
CGDisplayRegisterReconfigurationCallback(displays_arrangement_changed, NULL); 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]; window_delegate = [[GodotWindowDelegate alloc] init];
// Don't use accumulation buffer support; it's not accelerated // 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 (displayScale > 1.0) {
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
[window_view setWantsBestResolutionOpenGLSurface:YES]; if (video_driver_index == VIDEO_DRIVER_GLES2) {
[window_view setWantsBestResolutionOpenGLSurface:YES];
}
#endif #endif
//if (current_videomode.resizable)
[window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; [window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
} else { } else {
[window_view setWantsBestResolutionOpenGLSurface:NO]; [window_view setWantsBestResolutionOpenGLSurface:NO];
} }
//[window_object setTitle:[NSString stringWithUTF8String:"GodotEnginies"]];
[window_object setContentView:window_view]; [window_object setContentView:window_view];
[window_object setDelegate:window_delegate]; [window_object setDelegate:window_delegate];
[window_object setAcceptsMouseMovedEvents:YES]; [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]; [window_object setRestorable:NO];
// Init context and rendering device
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); if (video_driver_index == VIDEO_DRIVER_GLES2) {
ERR_FAIL_COND(!framework);
unsigned int attributeCount = 0; context_gles2 = memnew(ContextGL_OSX(window_view, false));
// OS X needs non-zero color size, so set reasonable values if (context_gles2->initialize() != OK) {
int colorBits = 32; memdelete(context_gles2);
context_gles2 = NULL;
ERR_FAIL_V(ERR_UNAVAILABLE);
}
// Fail if a robustness strategy was requested context_gles2->set_use_vsync(p_desired.use_vsync);
#define ADD_ATTR(x) \
{ attributes[attributeCount++] = x; } if (RasterizerGLES2::is_viable() == OK) {
#define ADD_ATTR2(x, y) \ RasterizerGLES2::register_config();
{ \ RasterizerGLES2::make_current();
ADD_ATTR(x); \ } else {
ADD_ATTR(y); \ 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 context_vulkan = memnew(VulkanContextOSX);
NSOpenGLPixelFormatAttribute attributes[40]; 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); rendering_device_vulkan = memnew(RenderingDeviceVulkan);
ADD_ATTR(NSOpenGLPFAClosestPolicy); rendering_device_vulkan->initialize(context_vulkan);
if (p_video_driver == VIDEO_DRIVER_GLES2) { RasterizerRD::make_current();
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_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 #endif
[NSApp activateIgnoringOtherApps:YES]; [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) if (p_desired.fullscreen)
zoomed = true; 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); visual_server = memnew(VisualServerRaster);
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
@ -1734,6 +1619,27 @@ void OS_OSX::finalize() {
midi_driver.close(); midi_driver.close();
#endif #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); CFNotificationCenterRemoveObserver(CFNotificationCenterGetDistributedCenter(), NULL, kTISNotifySelectedKeyboardInputSourceChanged, NULL);
CGDisplayRemoveReconfigurationCallback(displays_arrangement_changed, NULL); CGDisplayRemoveReconfigurationCallback(displays_arrangement_changed, NULL);
@ -1745,15 +1651,6 @@ void OS_OSX::finalize() {
cursors_cache.clear(); cursors_cache.clear();
visual_server->finish(); visual_server->finish();
memdelete(visual_server); 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) { 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() { void OS_OSX::release_rendering_thread() {
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
[NSOpenGLContext clearCurrentContext]; if (video_driver_index == VIDEO_DRIVER_GLES2) {
context_gles2->release_current();
}
#endif #endif
} }
void OS_OSX::make_rendering_thread() { void OS_OSX::make_rendering_thread() {
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
[context makeCurrentContext]; if (video_driver_index == VIDEO_DRIVER_GLES2) {
context_gles2->make_current();
}
#endif #endif
} }
@ -2320,10 +2221,15 @@ String OS_OSX::get_locale() const {
} }
void OS_OSX::swap_buffers() { void OS_OSX::swap_buffers() {
[context flushBuffer]; #if defined(OPENGL_ENABLED)
if (video_driver_index == VIDEO_DRIVER_GLES2) {
context_gles2->swap_buffers();
}
#endif #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
context_vulkan->swap_buffers(); if (video_driver_index == VIDEO_DRIVER_VULKAN) {
context_vulkan->swap_buffers();
}
#endif #endif
} }
@ -2738,8 +2644,9 @@ void OS_OSX::set_window_per_pixel_transparency_enabled(bool p_enabled) {
[window_object setOpaque:NO]; [window_object setOpaque:NO];
[window_object setHasShadow:NO]; [window_object setHasShadow:NO];
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
GLint opacity = 0; if (video_driver_index == VIDEO_DRIVER_GLES2) {
[context setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity]; context_gles2->set_opacity(0);
}
#endif #endif
layered_window = true; layered_window = true;
} else { } else {
@ -2747,13 +2654,16 @@ void OS_OSX::set_window_per_pixel_transparency_enabled(bool p_enabled) {
[window_object setOpaque:YES]; [window_object setOpaque:YES];
[window_object setHasShadow:YES]; [window_object setHasShadow:YES];
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
GLint opacity = 1; if (video_driver_index == VIDEO_DRIVER_GLES2) {
[context setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity]; context_gles2->set_opacity(1);
}
#endif #endif
layered_window = false; layered_window = false;
} }
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
[context update]; if (video_driver_index == VIDEO_DRIVER_GLES2) {
context_gles2->update();
}
#endif #endif
NSRect frame = [window_object frame]; NSRect frame = [window_object frame];
[window_object setFrame:NSMakeRect(frame.origin.x, frame.origin.y, 1, 1) display:YES]; [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) { void OS_OSX::_set_use_vsync(bool p_enable) {
// FIXME: Commented out during rebase of vulkan branch on master.
/*
CGLContextObj ctx = CGLGetCurrentContext(); CGLContextObj ctx = CGLGetCurrentContext();
if (ctx) { if (ctx) {
GLint swapInterval = p_enable ? 1 : 0; GLint swapInterval = p_enable ? 1 : 0;
CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval); 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; OS_OSX *OS_OSX::singleton = NULL;

View file

@ -13,14 +13,11 @@ common_win = [
"key_mapping_windows.cpp", "key_mapping_windows.cpp",
"joypad_windows.cpp", "joypad_windows.cpp",
"power_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_file = 'godot_res.rc'
res_target = "godot_res" + env["OBJSUFFIX"] res_target = "godot_res" + env["OBJSUFFIX"]
res_obj = env.RES(res_target, res_file) res_obj = env.RES(res_target, res_file)

View file

@ -224,16 +224,15 @@ def configure_msvc(env, manual_msvc_config):
'shell32', 'advapi32', 'dinput8', 'dxguid', 'imm32', 'bcrypt', 'Avrt', 'shell32', 'advapi32', 'dinput8', 'dxguid', 'imm32', 'bcrypt', 'Avrt',
'dwmapi'] 'dwmapi']
if (env["renderer"] == "vulkan"): env.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"])
env.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"]) env.AppendUnique(CPPDEFINES = ['VULKAN_ENABLED'])
env.AppendUnique(CPPDEFINES = ['VULKAN_ENABLED']) if not env["builtin_vulkan_loader"]:
if not env["builtin_vulkan_loader"]: LIBS += ['vulkan']
LIBS += ['vulkan']
else:
LIBS += ['cfgmgr32']
else: else:
env.AppendUnique(CPPDEFINES = ['OPENGL_ENABLED']) LIBS += ['cfgmgr32']
LIBS += ['opengl32']
#env.AppendUnique(CPPDEFINES = ['OPENGL_ENABLED'])
LIBS += ['opengl32']
env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in LIBS]) 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(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']) 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.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"]) env.Append(CPPDEFINES=['VULKAN_ENABLED'])
env.Append(CPPDEFINES=['VULKAN_ENABLED']) if not env["builtin_vulkan_loader"]:
if not env["builtin_vulkan_loader"]: env.Append(LIBS=['vulkan'])
env.Append(LIBS=['vulkan'])
else:
env.Append(LIBS=['cfgmgr32'])
else: else:
env.Append(CPPDEFINES=['OPENGL_ENABLED']) env.Append(LIBS=['cfgmgr32'])
env.Append(LIBS=['opengl32'])
## 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)]) env.Append(CPPDEFINES=['MINGW_ENABLED', ('MINGW_HAS_SECURE_API', 1)])

View file

@ -38,10 +38,10 @@
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
#include "drivers/gles2/rasterizer_gles2.h" #include "drivers/gles2/rasterizer_gles2.h"
#include "drivers/gles3/rasterizer_gles3.h"
#endif #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
#include "servers/visual/rasterizer/rasterizer_rd.h" #include "servers/visual/rasterizer_rd/rasterizer_rd.h"
#endif #endif
#include "drivers/windows/dir_access_windows.h" #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)); set_window_size(Size2(video_mode.width, video_mode.height));
} }
#if defined(VULKAN_ENABLED) #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 #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); SetWindowPos(hWnd, video_mode.always_on_top ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
} }
#if defined(OPENGL_ENABLED) //!!!!!!!!!!!!!!!!!!!!!!!!!!
//TODO - do Vulkan and GLES2 support checks, driver selection and fallback
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;
}
video_driver_index = p_video_driver; 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); // Init context and rendering device
set_vsync_via_compositor(video_mode.vsync_via_compositor); #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 #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
video_driver_index = VIDEO_DRIVER_VULKAN; if (video_driver_index == VIDEO_DRIVER_VULKAN) {
context_vulkan = memnew(VulkanContextWindows); context_vulkan = memnew(VulkanContextWindows);
context_vulkan->initialize(); if (context_vulkan->initialize() != OK) {
context_vulkan->window_create(hWnd, hInstance, get_video_mode().width, get_video_mode().height); 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 //temporary
rendering_device = memnew(RenderingDeviceVulkan); rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device->initialize(context_vulkan); rendering_device_vulkan->initialize(context_vulkan);
RasterizerRD::make_current();
RasterizerRD::make_current();
}
#endif #endif
visual_server = memnew(VisualServerRaster); visual_server = memnew(VisualServerRaster);
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
@ -1681,16 +1653,26 @@ void OS_Windows::finalize() {
cursors_cache.clear(); cursors_cache.clear();
visual_server->finish(); visual_server->finish();
memdelete(visual_server); memdelete(visual_server);
#ifdef OPENGL_ENABLED
if (gl_context) #if defined(OPENGL_ENABLED)
memdelete(gl_context); if (video_driver_index == VIDEO_DRIVER_GLES2) {
if (context_gles2)
memdelete(context_gles2);
}
#endif #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
rendering_device->finalize(); if (video_driver_index == VIDEO_DRIVER_VULKAN) {
memdelete(rendering_device);
memdelete(context_vulkan); if (rendering_device_vulkan) {
rendering_device_vulkan->finalize();
memdelete(rendering_device_vulkan);
}
if (context_vulkan)
memdelete(context_vulkan);
}
#endif #endif
if (user_proc) { if (user_proc) {
@ -1992,9 +1974,10 @@ void OS_Windows::set_window_size(const Size2 p_size) {
video_mode.width = w; video_mode.width = w;
video_mode.height = h; video_mode.height = h;
#if defined(VULKAN_ENABLED) #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 #endif
if (video_mode.fullscreen) { if (video_mode.fullscreen) {
@ -3154,22 +3137,30 @@ OS::LatinKeyboardVariant OS_Windows::get_latin_keyboard_variant() const {
void OS_Windows::release_rendering_thread() { void OS_Windows::release_rendering_thread() {
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
gl_context->release_current(); if (video_driver_index == VIDEO_DRIVER_GLES2) {
context_gles2->release_current();
}
#endif #endif
} }
void OS_Windows::make_rendering_thread() { void OS_Windows::make_rendering_thread() {
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
gl_context->make_current(); if (video_driver_index == VIDEO_DRIVER_GLES2) {
context_gles2->make_current();
}
#endif #endif
} }
void OS_Windows::swap_buffers() { void OS_Windows::swap_buffers() {
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
gl_context->swap_buffers(); if (video_driver_index == VIDEO_DRIVER_GLES2) {
context_gles2->swap_buffers();
}
#endif #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
context_vulkan->swap_buffers(); if (video_driver_index == VIDEO_DRIVER_VULKAN) {
context_vulkan->swap_buffers();
}
#endif #endif
} }
@ -3338,18 +3329,12 @@ String OS_Windows::get_joy_guid(int p_device) const {
void OS_Windows::_set_use_vsync(bool p_enable) { void OS_Windows::_set_use_vsync(bool p_enable) {
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
if (gl_context) if (video_driver_index == VIDEO_DRIVER_GLES2) {
gl_context->set_use_vsync(p_enable); if (context_gles2)
context_gles2->set_use_vsync(p_enable);
}
#endif #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() { OS::PowerState OS_Windows::get_power_state() {
return power_manager->get_power_state(); return power_manager->get_power_state();

View file

@ -178,13 +178,14 @@ class OS_Windows : public OS {
bool outside; bool outside;
int old_x, old_y; int old_x, old_y;
Point2i center; Point2i center;
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
ContextGL_Windows *gl_context; ContextGL_Windows *context_gles2;
#endif #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
VulkanContextWindows *context_vulkan; VulkanContextWindows *context_vulkan;
RenderingDeviceVulkan *rendering_device; RenderingDeviceVulkan *rendering_device_vulkan;
#endif #endif
VisualServer *visual_server; VisualServer *visual_server;

View file

@ -6,7 +6,7 @@ from platform_methods import run_in_subprocess
import platform_x11_builders import platform_x11_builders
common_x11 = [ common_x11 = [
#"context_gl_x11.cpp", "context_gl_x11.cpp",
"vulkan_context_x11.cpp", "vulkan_context_x11.cpp",
"crash_handler_x11.cpp", "crash_handler_x11.cpp",
"os_x11.cpp", "os_x11.cpp",

View file

@ -320,14 +320,13 @@ def configure(env):
env.Prepend(CPPPATH=['#platform/x11']) env.Prepend(CPPPATH=['#platform/x11'])
env.Append(CPPDEFINES=['X11_ENABLED', 'UNIX_ENABLED']) env.Append(CPPDEFINES=['X11_ENABLED', 'UNIX_ENABLED'])
if (env["renderer"] == "vulkan"): env.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"])
env.Prepend(CPPPATH=['#thirdparty/vulkan/include/', "#thirdparty/vulkan/registry/"]) env.Append(CPPDEFINES=['VULKAN_ENABLED'])
env.Append(CPPDEFINES=['VULKAN_ENABLED']) if not env["builtin_vulkan_loader"]:
if not env["builtin_vulkan_loader"]: env.Append(LIBS=['vulkan'])
env.Append(LIBS=['vulkan'])
else: #env.Append(CPPDEFINES=['OPENGL_ENABLED'])
env.Append(CPPDEFINES=['OPENGL_ENABLED']) env.Append(LIBS=['GL'])
env.Append(LIBS=['GL'])
env.Append(LIBS=['pthread']) env.Append(LIBS=['pthread'])

View file

@ -33,11 +33,17 @@
#include "core/os/dir_access.h" #include "core/os/dir_access.h"
#include "core/print_string.h" #include "core/print_string.h"
//#include "drivers/gles2/rasterizer_gles2.h"
//#include "drivers/gles3/rasterizer_gles3.h"
#include "errno.h" #include "errno.h"
#include "key_mapping_x11.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" #include "servers/visual/rasterizer_rd/rasterizer_rd.h"
#endif
#include "servers/visual/visual_server_raster.h" #include "servers/visual/visual_server_raster.h"
#include "servers/visual/visual_server_wrap_mt.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 { int OS_X11::get_current_video_driver() const {
return video_driver_index; 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) { Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
long im_event_mask = 0; 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); XFree(imvalret);
} }
/* //!!!!!!!!!!!!!!!!!!!!!!!!!!
char* windowid = getenv("GODOT_WINDOWID"); //TODO - do Vulkan and GLES2 support checks, driver selection and fallback
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<String> 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;
}
video_driver_index = p_video_driver; 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; long visualMask = VisualScreenMask;
int numberOfVisuals; int numberOfVisuals;
XVisualInfo vInfoTemplate = {}; 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.background_pixel = 0xFFFFFFFF;
windowAttributes.border_pixel = 0; windowAttributes.border_pixel = 0;
windowAttributes.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask | ExposureMask; 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; 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); 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); XFree(visualInfo);
context_vulkan = memnew(VulkanContextX11); // Init context and rendering device
context_vulkan->initialize(); #if defined(OPENGL_ENABLED)
context_vulkan->window_create(x11_window, x11_display, get_video_mode().width, get_video_mode().height); if (video_driver_index == VIDEO_DRIVER_GLES2) {
if (getenv("DRI_PRIME") == NULL) {
int use_prime = -1;
//temporary if (getenv("PRIMUS_DISPLAY") ||
rendering_device = memnew(RenderingDeviceVulkan); getenv("PRIMUS_libGLd") ||
rendering_device->initialize(context_vulkan); getenv("PRIMUS_libGLa") ||
RasterizerRD::make_current(); getenv("PRIMUS_libGL") ||
getenv("PRIMUS_LOAD_GLOBAL") ||
getenv("BUMBLEBEE_SOCKET")) {
// test shader print_verbose("Optirun/primusrun detected. Skipping GPU detection");
#if 0 use_prime = 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 }";
RenderingDevice::ShaderStageSource frag; if (getenv("LD_LIBRARY_PATH")) {
frag.shader_stage = RenderingDevice::SHADER_STAGE_FRAGMENT; String ld_library_path(getenv("LD_LIBRARY_PATH"));
frag.shader_source = "#version 450\n" Vector<String> libraries = ld_library_path.split(":");
"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";
Vector<RenderingDevice::ShaderStageSource> source; for (int i = 0; i < libraries.size(); ++i) {
source.push_back(vert); if (FileAccess::exists(libraries[i] + "/libGL.so.1") ||
source.push_back(frag); FileAccess::exists(libraries[i] + "/libGL.so")) {
String error;
shader = rendering_device->shader_create_from_source(source, &error); print_verbose("Custom libGL override detected. Skipping GPU detection");
if (!shader.is_valid()) { use_prime = 0;
print_line("failed compilation: " + error); }
}
}
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 { } else {
print_line("compilation success"); memdelete(context_gles2);
context_gles2 = NULL;
ERR_FAIL_V(ERR_UNAVAILABLE);
} }
} }
RenderingDevice::VertexFormatID vertex_desc;
{
PoolVector<uint8_t> pv;
pv.resize(24 * 4);
{
PoolVector<uint8_t>::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<RenderingDevice::VertexDescription> 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<RID> 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<RID> 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<Image> 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<PoolVector<uint8_t> > 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<RenderingDevice::Uniform> 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<uint8_t> pv;
pv.resize(6 * 4);
{
PoolVector<uint8_t>::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<RenderingDevice::Uniform> 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<RenderingDevice::ShaderStageSource> 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 #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 #endif
visual_server = memnew(VisualServerRaster); visual_server = memnew(VisualServerRaster);
@ -1164,24 +865,35 @@ void OS_X11::finalize() {
visual_server->finish(); visual_server->finish();
memdelete(visual_server); memdelete(visual_server);
rendering_device->finalize();
memdelete(rendering_device);
memdelete(context_vulkan);
//memdelete(rasterizer);
memdelete(power_manager); 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) if (xrandr_handle)
dlclose(xrandr_handle); dlclose(xrandr_handle);
XUnmapWindow(x11_display, x11_window); XUnmapWindow(x11_display, x11_window);
XDestroyWindow(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++) { for (int i = 0; i < CURSOR_MAX; i++) {
if (cursors[i] != None) if (cursors[i] != None)
XFreeCursor(x11_display, cursors[i]); XFreeCursor(x11_display, cursors[i]);
@ -2423,7 +2135,12 @@ void OS_X11::_window_changed(XEvent *event) {
current_videomode.width = event->xconfigure.width; current_videomode.width = event->xconfigure.width;
current_videomode.height = event->xconfigure.height; 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() { 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() { void OS_X11::release_rendering_thread() {
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
context_gl->release_current(); if (video_driver_index == VIDEO_DRIVER_GLES2) {
context_gles2->release_current();
}
#endif #endif
} }
void OS_X11::make_rendering_thread() { void OS_X11::make_rendering_thread() {
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
context_gl->make_current(); if (video_driver_index == VIDEO_DRIVER_GLES2) {
context_gles2->make_current();
}
#endif #endif
} }
void OS_X11::swap_buffers() { void OS_X11::swap_buffers() {
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
context_gl->swap_buffers(); if (video_driver_index == VIDEO_DRIVER_GLES2) {
context_gles2->swap_buffers();
}
#endif #endif
#if 0 #if defined(VULKAN_ENABLED)
Vector <Color> clear; if (video_driver_index == VIDEO_DRIVER_VULKAN) {
float color[4] = { 1, 0, 1, 1 }; context_vulkan->swap_buffers();
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();
#endif #endif
context_vulkan->swap_buffers();
} }
void OS_X11::alert(const String &p_alert, const String &p_title) { 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) { void OS_X11::_set_use_vsync(bool p_enable) {
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
if (context_gl) if (video_driver_index == VIDEO_DRIVER_GLES2) {
context_gl->set_use_vsync(p_enable); if (context_gles2)
context_gles2->set_use_vsync(p_enable);
}
#endif #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) { void OS_X11::set_context(int p_context) {
XClassHint *classHint = XAllocClassHint(); XClassHint *classHint = XAllocClassHint();

View file

@ -31,7 +31,6 @@
#ifndef OS_X11_H #ifndef OS_X11_H
#define OS_X11_H #define OS_X11_H
//#include "context_gl_x11.h"
#include "core/os/input.h" #include "core/os/input.h"
#include "crash_handler_x11.h" #include "crash_handler_x11.h"
#include "drivers/alsa/audio_driver_alsa.h" #include "drivers/alsa/audio_driver_alsa.h"
@ -44,9 +43,15 @@
#include "servers/audio_server.h" #include "servers/audio_server.h"
#include "servers/visual/rasterizer.h" #include "servers/visual/rasterizer.h"
#include "servers/visual_server.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 "drivers/vulkan/rendering_device_vulkan.h"
#include "platform/x11/vulkan_context_x11.h" #include "platform/x11/vulkan_context_x11.h"
#endif
#include <X11/Xcursor/Xcursor.h> #include <X11/Xcursor/Xcursor.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -94,11 +99,11 @@ class OS_X11 : public OS_Unix {
int xdnd_version; int xdnd_version;
#if defined(OPENGL_ENABLED) #if defined(OPENGL_ENABLED)
ContextGL_X11 *context_gl; ContextGL_X11 *context_gles2;
#endif #endif
#if defined(VULKAN_ENABLED) #if defined(VULKAN_ENABLED)
VulkanContextX11 *context_vulkan; VulkanContextX11 *context_vulkan;
RenderingDeviceVulkan *rendering_device; RenderingDeviceVulkan *rendering_device_vulkan;
#endif #endif
//Rasterizer *rasterizer; //Rasterizer *rasterizer;

View file

@ -2094,6 +2094,10 @@ EffectsRD *RasterizerStorageRD::get_effects() {
RasterizerStorageRD::RasterizerStorageRD() { RasterizerStorageRD::RasterizerStorageRD() {
for (int i = 0; i < SHADER_TYPE_MAX; i++) {
shader_data_request_func[i] = NULL;
}
material_update_list = NULL; material_update_list = NULL;
{ //create default textures { //create default textures