compilable (not linkable yet) on linux

This commit is contained in:
Mikulas Florek 2020-02-06 18:51:29 +01:00
parent 1c00f5e031
commit 963be7a0f2
38 changed files with 656 additions and 772 deletions

BIN
projects/genie Executable file

Binary file not shown.

View file

@ -184,7 +184,7 @@ if _OPTIONS["no-lua-script"] == nil then
table.insert(base_plugins, "lua_script") table.insert(base_plugins, "lua_script")
end end
if _OPTIONS["no-gui"] == nil or _ACTION ~= "vs2019" then if _OPTIONS["no-gui"] == nil then
table.insert(plugins, "gui") table.insert(plugins, "gui")
table.insert(base_plugins, "gui") table.insert(base_plugins, "gui")
end end
@ -223,7 +223,6 @@ newoption {
value = "GCC", value = "GCC",
description = "Choose GCC flavor", description = "Choose GCC flavor",
allowed = { allowed = {
{ "android-x86", "Android - x86" },
{ "linux-gcc", "Linux (GCC compiler)" }, { "linux-gcc", "Linux (GCC compiler)" },
{ "linux-gcc-5", "Linux (GCC-5 compiler)" }, { "linux-gcc-5", "Linux (GCC-5 compiler)" },
{ "linux-clang", "Linux (Clang compiler)" } { "linux-clang", "Linux (Clang compiler)" }
@ -242,7 +241,6 @@ function defaultConfigurations()
flags { "Symbols", "Optimize" } flags { "Symbols", "Optimize" }
configuration "linux" configuration "linux"
buildoptions { "-std=c++14" }
defines { "_GLIBCXX_USE_CXX11_ABI=0" } defines { "_GLIBCXX_USE_CXX11_ABI=0" }
links { "pthread" } links { "pthread" }
@ -363,87 +361,7 @@ end
solution "LumixEngine" solution "LumixEngine"
flags { "Cpp17" } flags { "Cpp17" }
if _ACTION == "gmake" then if _ACTION == "gmake" then
configuration { "android-*" } if "linux-gcc" == _OPTIONS["gcc"] then
flags {
"NoImportLib",
}
includedirs {
"$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/include",
"$(ANDROID_NDK_ROOT)/sources/android/native_app_glue",
}
linkoptions {
"-nostdlib",
"-static-libgcc",
}
links {
"c",
"dl",
"m",
"android",
"log",
"gnustl_static",
"gcc",
}
buildoptions {
"-fPIC",
"-no-canonical-prefixes",
"-Wa,--noexecstack",
"-fstack-protector",
"-ffunction-sections",
"-Wno-psabi",
"-Wunused-value",
"-Wundef",
}
buildoptions_cpp {
"-std=c++14",
}
linkoptions {
"-no-canonical-prefixes",
"-Wl,--no-undefined",
"-Wl,-z,noexecstack",
"-Wl,-z,relro",
"-Wl,-z,now",
}
configuration { "android-x86" }
androidPlatform = "android-24"
libdirs {
path.join(_libDir, "lib/android-x86"),
"$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/libs/x86",
}
includedirs {
"$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/libs/x86/include",
}
buildoptions {
"--sysroot=" .. path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-x86"),
"-march=i686",
"-mtune=atom",
"-mstackrealign",
"-msse3",
"-mfpmath=sse",
"-Wunused-value",
"-Wundef",
}
linkoptions {
"--sysroot=" .. path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-x86"),
path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-x86/usr/lib/crtbegin_so.o"),
path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-x86/usr/lib/crtend_so.o"),
}
configuration {}
if "android-x86" == _OPTIONS["gcc"] then
if not os.getenv("ANDROID_NDK_X86") or not os.getenv("ANDROID_NDK_ROOT") then
print("Set ANDROID_NDK_X86 and ANDROID_NDK_ROOT envrionment variables.")
end
premake.gcc.cc = "\"$(ANDROID_NDK_X86)/bin/i686-linux-android-gcc\""
premake.gcc.cxx = "\"$(ANDROID_NDK_X86)/bin/i686-linux-android-g++\""
premake.gcc.ar = "\"$(ANDROID_NDK_X86)/bin/i686-linux-android-ar\""
LOCATION = "tmp/android-x86_gmake"
elseif "linux-gcc" == _OPTIONS["gcc"] then
LOCATION = "tmp/gcc" LOCATION = "tmp/gcc"
elseif "linux-gcc-5" == _OPTIONS["gcc"] then elseif "linux-gcc-5" == _OPTIONS["gcc"] then
@ -466,8 +384,9 @@ solution "LumixEngine"
removefiles { "../src/**/editor/*" } removefiles { "../src/**/editor/*" }
end end
configuration { "linux-*" } configuration { "linux" }
buildoptions { buildoptions {
"-m64",
"-fPIC", "-fPIC",
"-no-canonical-prefixes", "-no-canonical-prefixes",
"-Wa,--noexecstack", "-Wa,--noexecstack",
@ -477,20 +396,12 @@ solution "LumixEngine"
"-Wunused-value", "-Wunused-value",
"-Wundef", "-Wundef",
"-msse2", "-msse2",
"-Wno-multichar",
"-Wno-undef",
} }
linkoptions { linkoptions {
"-Wl,--gc-sections", "-Wl,--gc-sections",
} }
configuration { "linux-*", "x32" }
buildoptions {
"-m32",
}
configuration { "linux-*", "x64" }
buildoptions {
"-m64",
}
configuration {} configuration {}
@ -520,12 +431,6 @@ solution "LumixEngine"
configuration "not windows" configuration "not windows"
removefiles { "../src/**/win/*"} removefiles { "../src/**/win/*"}
configuration "android-*"
removefiles { "../src/**/win/*"}
configuration "not asmjs"
removefiles { "../src/**/asmjs/*"}
if _OPTIONS["static-plugins"] then if _OPTIONS["static-plugins"] then
defines {"STATIC_PLUGINS"} defines {"STATIC_PLUGINS"}
end end

Binary file not shown.

View file

@ -8,8 +8,8 @@
#include "engine/crc32.h" #include "engine/crc32.h"
#include "engine/engine.h" #include "engine/engine.h"
#include "engine/lua_wrapper.h" #include "engine/lua_wrapper.h"
#include "engine/job_system.h"
#include "engine/mt/atomic.h" #include "engine/mt/atomic.h"
#include "engine/job_system.h"
#include "engine/profiler.h" #include "engine/profiler.h"
#include "engine/reflection.h" #include "engine/reflection.h"
#include "engine/resource_manager.h" #include "engine/resource_manager.h"

View file

@ -451,6 +451,16 @@ void GroupNode::deserialize(InputMemoryStream& stream, Controller& ctrl) {
} }
} }
void Node::serialize(OutputMemoryStream& stream) const {
stream.writeString(m_name.c_str());
}
void Node::deserialize(InputMemoryStream& stream, Controller& ctrl) {
char tmp[64];
stream.readString(Span(tmp));
m_name = tmp;
}
Node* Node::create(GroupNode* parent, Type type, IAllocator& allocator) { Node* Node::create(GroupNode* parent, Type type, IAllocator& allocator) {
switch (type) { switch (type) {
case Node::ANIMATION: return LUMIX_NEW(allocator, AnimationNode)(parent, allocator); case Node::ANIMATION: return LUMIX_NEW(allocator, AnimationNode)(parent, allocator);

View file

@ -53,15 +53,8 @@ struct Node {
virtual void enter(RuntimeContext& ctx) const = 0; virtual void enter(RuntimeContext& ctx) const = 0;
virtual void skip(RuntimeContext& ctx) const = 0; virtual void skip(RuntimeContext& ctx) const = 0;
virtual void getPose(RuntimeContext& ctx, float weight, Ref<Pose> pose, u32 mask) const = 0; virtual void getPose(RuntimeContext& ctx, float weight, Ref<Pose> pose, u32 mask) const = 0;
virtual void serialize(OutputMemoryStream& stream) const = 0 { virtual void serialize(OutputMemoryStream& stream) const = 0;
stream.writeString(m_name.c_str()); virtual void deserialize(InputMemoryStream& stream, Controller& ctrl) = 0;
}
virtual void deserialize(InputMemoryStream& stream, Controller& ctrl) = 0 {
char tmp[64];
stream.readString(Span(tmp));
m_name = tmp;
}
static Node* create(GroupNode* parent, Type type, IAllocator& allocator); static Node* create(GroupNode* parent, Type type, IAllocator& allocator);

View file

@ -1,11 +1,9 @@
#include "audio_device.h" #include "audio_device.h"
#include "clip_manager.h"
#include "engine/log.h" #include "engine/log.h"
#include "engine/engine.h" #include "engine/engine.h"
#include "engine/iplugin.h" #include "engine/iplugin.h"
#include "engine/log.h" #include "engine/log.h"
#include "engine/mt/task.h" #include "engine/mt/task.h"
#include "engine/system.h"
#include <alsa/asoundlib.h> #include <alsa/asoundlib.h>

View file

@ -1,6 +1,6 @@
#include "editor/platform_interface.h"
#include "engine/hash_map.h" #include "engine/hash_map.h"
#include "engine/mt/task.h" #include "engine/mt/task.h"
#include "engine/os.h"
#include "engine/profiler.h" #include "engine/profiler.h"
#include "engine/string.h" #include "engine/string.h"
#include "file_system_watcher.h" #include "file_system_watcher.h"
@ -66,7 +66,7 @@ struct FileSystemWatcherImpl : public FileSystemWatcher
bool start(const char* path) bool start(const char* path)
{ {
task = LUMIX_NEW(allocator, FileSystemWatcherTask)(path, *this, allocator); task = LUMIX_NEW(allocator, FileSystemWatcherTask)(path, *this, allocator);
if (!task->create("FileSystemWatcherTask")) if (!task->create("FileSystemWatcherTask", true))
{ {
LUMIX_DELETE(allocator, task); LUMIX_DELETE(allocator, task);
task = nullptr; task = nullptr;
@ -107,14 +107,14 @@ void FileSystemWatcher::destroy(FileSystemWatcher* watcher)
static void addWatch(FileSystemWatcherTask& task, const char* path, int root_length) static void addWatch(FileSystemWatcherTask& task, const char* path, int root_length)
{ {
if (!PlatformInterface::dirExists(path)) return; if (!OS::dirExists(path)) return;
int wd = inotify_add_watch(task.fd, path, IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO | IN_CLOSE_WRITE); int wd = inotify_add_watch(task.fd, path, IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO | IN_CLOSE_WRITE);
task.watched.insert(wd, path + root_length); task.watched.insert(wd, path + root_length);
auto iter = PlatformInterface::createFileIterator(path, task.allocator); auto iter = OS::createFileIterator(path, task.allocator);
PlatformInterface::FileInfo info; OS::FileInfo info;
while (PlatformInterface::getNextFile(iter, &info)) while (OS::getNextFile(iter, &info))
{ {
if (!info.is_directory) continue; if (!info.is_directory) continue;
if (Lumix::equalStrings(info.filename, ".")) continue; if (Lumix::equalStrings(info.filename, ".")) continue;
@ -123,7 +123,7 @@ static void addWatch(FileSystemWatcherTask& task, const char* path, int root_len
Lumix::StaticString<Lumix::MAX_PATH_LENGTH> tmp(path, info.filename, "/"); Lumix::StaticString<Lumix::MAX_PATH_LENGTH> tmp(path, info.filename, "/");
addWatch(task, tmp, root_length); addWatch(task, tmp, root_length);
} }
PlatformInterface::destroyFileIterator(iter); OS::destroyFileIterator(iter);
} }
@ -133,12 +133,12 @@ static void getName(FileSystemWatcherTask& task, inotify_event* event, char* out
if (iter == task.watched.end()) if (iter == task.watched.end())
{ {
Lumix::copyString(out, max_size, event->name); Lumix::copyString(Span(out, max_size), event->name);
return; return;
} }
Lumix::copyString(out, max_size, iter.value()); Lumix::copyString(Span(out, max_size), iter.value());
Lumix::catString(out, max_size, event->name); Lumix::catString(Span(out, max_size), event->name);
} }

View file

@ -6,10 +6,10 @@
#include "engine/engine.h" #include "engine/engine.h"
#include "engine/fibers.h" #include "engine/fibers.h"
#include "engine/file_system.h" #include "engine/file_system.h"
#include "engine/mt/atomic.h"
#include "engine/job_system.h" #include "engine/job_system.h"
#include "engine/log.h" #include "engine/log.h"
#include "engine/math.h" #include "engine/math.h"
#include "engine/mt/atomic.h"
#include "engine/os.h" #include "engine/os.h"
#include "engine/page_allocator.h" #include "engine/page_allocator.h"
#include "engine/profiler.h" #include "engine/profiler.h"

View file

@ -18,6 +18,7 @@
#include "engine/file_system.h" #include "engine/file_system.h"
#include "engine/geometry.h" #include "engine/geometry.h"
#include "engine/input_system.h" #include "engine/input_system.h"
#include "engine/mt/atomic.h"
#include "engine/job_system.h" #include "engine/job_system.h"
#include "engine/log.h" #include "engine/log.h"
#include "engine/lua_wrapper.h" #include "engine/lua_wrapper.h"

View file

@ -2228,7 +2228,7 @@ public:
return 0; return 0;
}; };
lua_pushlightuserdata(L, static_cast<void*>(creator)); lua_pushlightuserdata(L, reinterpret_cast<void*>(creator));
lua_pushlightuserdata(L, this); lua_pushlightuserdata(L, this);
lua_pushcclosure(L, f, 2); lua_pushcclosure(L, f, 2);
lua_setfield(L, -2, name); lua_setfield(L, -2, name);

View file

@ -2,78 +2,82 @@
#include "lumix.h" #include "lumix.h"
#ifndef _WIN32 #ifdef _WIN32
#error unsupported platform #define LUMIX_CRT_API LUMIX_LIBRARY_IMPORT
#endif #ifndef MCW_EM
#define _EM_OVERFLOW 0x00000004
#define LUMIX_CRT_API LUMIX_LIBRARY_IMPORT #define _EM_ZERODIVIDE 0x00000008
#ifndef MCW_EM #define _EM_INVALID 0x00000010
#define _EM_OVERFLOW 0x00000004 #define _EM_DENORMAL 0x00080000
#define _EM_ZERODIVIDE 0x00000008 #define MCW_EM 0x0008001f
#define _EM_INVALID 0x00000010
#define _EM_DENORMAL 0x00080000
#define MCW_EM 0x0008001f
#endif
#define DBL_MAX 1.7976931348623158e+308
#define DBL_MIN 2.2250738585072014e-308
#define FLT_MAX 3.402823466e+38F
#define FLT_MIN 1.175494351e-38F
#define NULL 0
#define PRId64 "lld"
extern "C" {
typedef char* va_list;
LUMIX_CRT_API void* __cdecl _aligned_malloc(size_t size, size_t align);
LUMIX_CRT_API void __cdecl _aligned_free(void* ptr);
LUMIX_CRT_API void* __cdecl _aligned_realloc(void* ptr, size_t size, size_t align);
LUMIX_CRT_API unsigned int __cdecl _control87(unsigned int value, unsigned int mask);
LUMIX_CRT_API int __cdecl _stricmp(const char* str1, const char* str2);
LUMIX_CRT_API int __cdecl _strncmp(const char* str1, const char* str2);
LUMIX_CRT_API int __cdecl _strnicmp(const char* str1, const char* str2, size_t max_count);
LUMIX_CRT_API __declspec(noreturn) void __cdecl abort(void);
LUMIX_CRT_API float __cdecl acosf(float x);
LUMIX_CRT_API float __cdecl atan2f(float y, float x);
LUMIX_CRT_API double __cdecl atof(const char* str);
LUMIX_CRT_API int __cdecl atoi(const char* str);
LUMIX_CRT_API double __cdecl ceil(double x);
LUMIX_CRT_API float __cdecl cosf(float x);
double __cdecl fabs(double x);
LUMIX_CRT_API double __cdecl floor(double _X);
#ifndef _INC_MATH
inline float __cdecl fabsf(float x) { return (float)fabs(x); }
#ifdef LUMIX_DEBUG
inline float __cdecl floorf(float x) { return (float)floor(x); }
#endif
LUMIX_CRT_API float __cdecl ceilf(float x);
//inline float __cdecl ceilf(float x) { return (float)ceil(x); }
#endif #endif
LUMIX_CRT_API float fmodf(float x, float y); #define DBL_MAX 1.7976931348623158e+308
double __cdecl fmod(double x, double y); #define DBL_MIN 2.2250738585072014e-308
LUMIX_CRT_API void __cdecl free(void* ptr); #define FLT_MAX 3.402823466e+38F
double __cdecl log10(double x); #define FLT_MIN 1.175494351e-38F
LUMIX_CRT_API void* __cdecl malloc(size_t size); #define NULL 0
const void* __cdecl memchr(const void* buf, int val, size_t max_count); #define PRId64 "lld"
int __cdecl memcmp(const void* buf1, const void* buf2, size_t size);
void* __cdecl memcpy(void* dst, void const* src, size_t size); __pragma(intrinsic(memcpy)) extern "C" {
void* __cdecl memmove(void* dst, const void* src, size_t size); typedef char* va_list;
void* __cdecl memset(void* dst, int val, size_t size); __pragma(intrinsic(memmove))
LUMIX_CRT_API float __cdecl powf(float x, float y); LUMIX_CRT_API void* __cdecl _aligned_malloc(size_t size, size_t align);
double __cdecl pow(double x, double y); __pragma(intrinsic(pow)) LUMIX_CRT_API void __cdecl _aligned_free(void* ptr);
LUMIX_CRT_API void __cdecl qsort(void* ptr, size_t count, size_t size, int(*cmp)(const void *, const void *)); LUMIX_CRT_API void* __cdecl _aligned_realloc(void* ptr, size_t size, size_t align);
LUMIX_CRT_API void* __cdecl realloc(void* ptr, size_t size); LUMIX_CRT_API unsigned int __cdecl _control87(unsigned int value, unsigned int mask);
LUMIX_CRT_API float __cdecl sinf(float x); LUMIX_CRT_API int __cdecl _stricmp(const char* str1, const char* str2);
LUMIX_CRT_API float __cdecl sqrtf(float x); LUMIX_CRT_API int __cdecl _strncmp(const char* str1, const char* str2);
const char* __cdecl strchr(const char* str, int val); LUMIX_CRT_API int __cdecl _strnicmp(const char* str1, const char* str2, size_t max_count);
size_t __cdecl strlen(const char* str);
int __cdecl strcmp(const char* str, const char* str2); LUMIX_CRT_API __declspec(noreturn) void __cdecl abort(void);
char* strcpy(char* dest, const char* src); LUMIX_CRT_API float __cdecl acosf(float x);
LUMIX_CRT_API int __cdecl strncmp(const char* str1, const char* str2, size_t max_count); LUMIX_CRT_API float __cdecl atan2f(float y, float x);
LUMIX_CRT_API char* strncpy(char *dest, const char *src, size_t n); LUMIX_CRT_API double __cdecl atof(const char* str);
const char* __cdecl strstr(const char* str, const char* substr); LUMIX_CRT_API int __cdecl atoi(const char* str);
LUMIX_CRT_API float __cdecl strtof(const char* str, char** end); LUMIX_CRT_API double __cdecl ceil(double x);
double __cdecl tan(double _X); LUMIX_CRT_API float __cdecl cosf(float x);
LUMIX_CRT_API float __cdecl tanf(float x); double __cdecl fabs(double x);
} LUMIX_CRT_API double __cdecl floor(double _X);
#ifndef _INC_MATH
inline float __cdecl fabsf(float x) { return (float)fabs(x); }
#ifdef LUMIX_DEBUG
inline float __cdecl floorf(float x) { return (float)floor(x); }
#endif
LUMIX_CRT_API float __cdecl ceilf(float x);
//inline float __cdecl ceilf(float x) { return (float)ceil(x); }
#endif
LUMIX_CRT_API float fmodf(float x, float y);
double __cdecl fmod(double x, double y);
LUMIX_CRT_API void __cdecl free(void* ptr);
double __cdecl log10(double x);
LUMIX_CRT_API void* __cdecl malloc(size_t size);
const void* __cdecl memchr(const void* buf, int val, size_t max_count);
int __cdecl memcmp(const void* buf1, const void* buf2, size_t size);
void* __cdecl memcpy(void* dst, void const* src, size_t size); __pragma(intrinsic(memcpy))
void* __cdecl memmove(void* dst, const void* src, size_t size);
void* __cdecl memset(void* dst, int val, size_t size); __pragma(intrinsic(memmove))
LUMIX_CRT_API float __cdecl powf(float x, float y);
double __cdecl pow(double x, double y); __pragma(intrinsic(pow))
LUMIX_CRT_API void __cdecl qsort(void* ptr, size_t count, size_t size, int(*cmp)(const void *, const void *));
LUMIX_CRT_API void* __cdecl realloc(void* ptr, size_t size);
LUMIX_CRT_API float __cdecl sinf(float x);
LUMIX_CRT_API float __cdecl sqrtf(float x);
const char* __cdecl strchr(const char* str, int val);
size_t __cdecl strlen(const char* str);
int __cdecl strcmp(const char* str, const char* str2);
char* strcpy(char* dest, const char* src);
LUMIX_CRT_API int __cdecl strncmp(const char* str1, const char* str2, size_t max_count);
LUMIX_CRT_API char* strncpy(char *dest, const char *src, size_t n);
const char* __cdecl strstr(const char* str, const char* substr);
LUMIX_CRT_API float __cdecl strtof(const char* str, char** end);
double __cdecl tan(double _X);
LUMIX_CRT_API float __cdecl tanf(float x);
}
#elif defined(__linux__)
#include <float.h>
#include <inttypes.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
inline int stricmp(const char* a, const char* b) { return strcasecmp(a, b); }
#endif

View file

@ -6,6 +6,7 @@
#include "engine/file_system.h" #include "engine/file_system.h"
#include "engine/input_system.h" #include "engine/input_system.h"
#include "engine/iplugin.h" #include "engine/iplugin.h"
#include "engine/mt/atomic.h"
#include "engine/job_system.h" #include "engine/job_system.h"
#include "engine/log.h" #include "engine/log.h"
#include "engine/lua_wrapper.h" #include "engine/lua_wrapper.h"

View file

@ -18,13 +18,14 @@ namespace Fiber
#ifdef _WIN32 #ifdef _WIN32
typedef void* Handle; using Handle = void*;
typedef void(__stdcall *FiberProc)(void*); using FiberProc = void(__stdcall *)(void*);
constexpr Handle INVALID_FIBER = nullptr;
#else #else
typedef ucontext_t Handle; using Handle = ucontext_t*;
typedef void (*FiberProc)(void*); using FiberProc = void (*)(void*);
constexpr Handle INVALID_FIBER = nullptr;
#endif #endif
constexpr void* INVALID_FIBER = nullptr;
void initThread(FiberProc proc, Handle* handle); void initThread(FiberProc proc, Handle* handle);

View file

@ -133,14 +133,14 @@ private:
HM* hm; HM* hm;
u32 idx; u32 idx;
template <typename HM, typename K, typename V> template <typename HM2, typename K2, typename V2>
bool operator !=(const iterator_base<HM, K, V>& rhs) const { bool operator !=(const iterator_base<HM2, K2, V2>& rhs) const {
ASSERT(hm == rhs.hm); ASSERT(hm == rhs.hm);
return idx != rhs.idx; return idx != rhs.idx;
} }
template <typename HM, typename K, typename V> template <typename HM2, typename K2, typename V2>
bool operator ==(const iterator_base<HM, K, V>& rhs) const { bool operator ==(const iterator_base<HM2, K2, V2>& rhs) const {
ASSERT(hm == rhs.hm); ASSERT(hm == rhs.hm);
return idx == rhs.idx; return idx == rhs.idx;
} }

View file

@ -1,3 +1,4 @@
#include "engine/mt/atomic.h"
#include "job_system.h" #include "job_system.h"
#include "engine/array.h" #include "engine/array.h"
#include "engine/engine.h" #include "engine/engine.h"
@ -5,7 +6,6 @@
#include "engine/allocator.h" #include "engine/allocator.h"
#include "engine/log.h" #include "engine/log.h"
#include "engine/math.h" #include "engine/math.h"
#include "engine/mt/atomic.h"
#include "engine/mt/sync.h" #include "engine/mt/sync.h"
#include "engine/mt/task.h" #include "engine/mt/task.h"
#include "engine/mt/thread.h" #include "engine/mt/thread.h"

View file

@ -1,5 +1,5 @@
#include "engine/allocator.h"
#include "engine/controller_device.h" #include "engine/controller_device.h"
#include "engine/iallocator.h"

View file

@ -1,7 +1,6 @@
#include "engine/debug/debug.h" #include "engine/debug.h"
#include "engine/mt/atomic.h" #include "engine/mt/atomic.h"
#include "engine/string.h" #include "engine/string.h"
#include "engine/system.h"
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
@ -64,7 +63,7 @@ void StackTree::refreshModuleList()
} }
int StackTree::getPath(StackNode* node, StackNode** output, int max_size) int StackTree::getPath(StackNode* node, Span<StackNode*> output)
{ {
return 0; return 0;
} }
@ -76,7 +75,7 @@ StackNode* StackTree::getParent(StackNode* node)
} }
bool StackTree::getFunction(StackNode* node, char* out, int max_size, int* line) bool StackTree::getFunction(StackNode* node, Span<char> out, Ref<int> line)
{ {
return false; return false;
} }
@ -108,7 +107,6 @@ static const u32 ALLOCATION_GUARD = 0xFDFDFDFD;
Allocator::Allocator(IAllocator& source) Allocator::Allocator(IAllocator& source)
: m_source(source) : m_source(source)
, m_root(nullptr) , m_root(nullptr)
, m_mutex(false)
, m_total_size(0) , m_total_size(0)
, m_is_fill_enabled(true) , m_is_fill_enabled(true)
, m_are_guards_enabled(true) , m_are_guards_enabled(true)
@ -151,13 +149,13 @@ Allocator::~Allocator()
void Allocator::lock() void Allocator::lock()
{ {
m_mutex.lock(); m_mutex.enter();
} }
void Allocator::unlock() void Allocator::unlock()
{ {
m_mutex.unlock(); m_mutex.exit();
} }

View file

@ -12,38 +12,41 @@ namespace Fiber
thread_local Handle g_finisher; thread_local Handle g_finisher;
thread_local ucontext_t g_finisher_obj;
void initThread(FiberProc proc, Handle* out) void initThread(FiberProc proc, Handle* out)
{ {
g_finisher = &g_finisher_obj;
*out = create(64*1024, proc, nullptr); *out = create(64*1024, proc, nullptr);
getcontext(&g_finisher); getcontext(g_finisher);
out->uc_link = &g_finisher; (*out)->uc_link = g_finisher;
switchTo(&g_finisher, *out); switchTo(&g_finisher, *out);
} }
Handle create(int stack_size, FiberProc proc, void* parameter) Handle create(int stack_size, FiberProc proc, void* parameter)
{ {
ucontext_t fib; ucontext_t* fib = new ucontext_t;
getcontext(&fib); getcontext(fib);
fib.uc_stack.ss_sp = (::malloc)(stack_size); fib->uc_stack.ss_sp = (::malloc)(stack_size);
fib.uc_stack.ss_size = stack_size; fib->uc_stack.ss_size = stack_size;
fib.uc_link = 0; fib->uc_link = 0;
makecontext(&fib, (void(*)())proc, 1, parameter); makecontext(fib, (void(*)())proc, 1, parameter);
return fib; return fib;
} }
void destroy(Handle fiber) void destroy(Handle fiber)
{ {
delete fiber;
ASSERT(false); ASSERT(false);
} }
void switchTo(Handle* prev, Handle fiber) void switchTo(Handle* prev, Handle fiber)
{ {
swapcontext(prev, &fiber); swapcontext(*prev, fiber);
} }

View file

@ -124,23 +124,89 @@ void get(lua_State* L, const char* head, Args... tail) {
get_tail(L, tail...); get_tail(L, tail...);
} }
template <typename T> inline bool checkField(lua_State* L, int idx, const char* k, T* out) template <typename T> inline bool isType(lua_State* L, int index)
{ {
lua_getfield(L, idx, k); return lua_islightuserdata(L, index) != 0;
if(!isType<T>(L, -1)) {
lua_pop(L, 1);
return false;
}
*out = toType<T>(L, -1);
lua_pop(L, 1);
return true;
} }
template <> inline bool isType<int>(lua_State* L, int index)
inline int getField(lua_State* L, int idx, const char* k)
{ {
lua_getfield(L, idx, k); return lua_isnumber(L, index) != 0;
return lua_type(L, -1); }
template <> inline bool isType<u16>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<Path>(lua_State* L, int index)
{
return lua_isstring(L, index);
}
template <> inline bool isType<u8>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<EntityRef>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<EntityPtr>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<ComponentType>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<Vec3>(lua_State* L, int index)
{
return lua_istable(L, index) != 0 && lua_objlen(L, index) == 3;
}
template <> inline bool isType<DVec3>(lua_State* L, int index)
{
return lua_istable(L, index) != 0 && lua_objlen(L, index) == 3;
}
template <> inline bool isType<Vec4>(lua_State* L, int index)
{
return lua_istable(L, index) != 0 && lua_objlen(L, index) == 4;
}
template <> inline bool isType<Vec2>(lua_State* L, int index)
{
return lua_istable(L, index) != 0 && lua_objlen(L, index) == 2;
}
template <> inline bool isType<Matrix>(lua_State* L, int index)
{
return lua_istable(L, index) != 0 && lua_objlen(L, index) == 16;
}
template <> inline bool isType<Quat>(lua_State* L, int index)
{
return lua_istable(L, index) != 0 && lua_objlen(L, index) == 4;
}
template <> inline bool isType<u32>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<u64>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<i64>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<bool>(lua_State* L, int index)
{
return lua_isboolean(L, index) != 0;
}
template <> inline bool isType<float>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<const char*>(lua_State* L, int index)
{
return lua_isstring(L, index) != 0;
}
template <> inline bool isType<void*>(lua_State* L, int index)
{
return lua_islightuserdata(L, index) != 0;
} }
template <typename T> inline T toType(lua_State* L, int index) template <typename T> inline T toType(lua_State* L, int index)
@ -148,31 +214,6 @@ template <typename T> inline T toType(lua_State* L, int index)
return (T)lua_touserdata(L, index); return (T)lua_touserdata(L, index);
} }
template <typename T, typename F> bool forEachArrayItem(lua_State* L, int index, const char* error_msg, F&& func)
{
if (!lua_istable(L, index)) {
if (error_msg) luaL_argerror(L, index, error_msg);
return false;
}
bool all_match = true;
const int n = (int)lua_objlen(L, index);
for (int i = 0; i < n; ++i) {
lua_rawgeti(L, index, i + 1);
if(isType<T>(L, -1)) {
func(toType<T>(L, -1));
}
else if (error_msg) {
lua_pop(L, 1);
luaL_argerror(L, index, error_msg);
}
else {
all_match = false;
}
lua_pop(L, 1);
}
return all_match;
}
template <> inline int toType(lua_State* L, int index) template <> inline int toType(lua_State* L, int index)
{ {
return (int)lua_tointeger(L, index); return (int)lua_tointeger(L, index);
@ -339,6 +380,51 @@ template <> inline void* toType(lua_State* L, int index)
return lua_touserdata(L, index); return lua_touserdata(L, index);
} }
template <typename T> inline bool checkField(lua_State* L, int idx, const char* k, T* out)
{
lua_getfield(L, idx, k);
if(!isType<T>(L, -1)) {
lua_pop(L, 1);
return false;
}
*out = toType<T>(L, -1);
lua_pop(L, 1);
return true;
}
inline int getField(lua_State* L, int idx, const char* k)
{
lua_getfield(L, idx, k);
return lua_type(L, -1);
}
template <typename T, typename F> bool forEachArrayItem(lua_State* L, int index, const char* error_msg, F&& func)
{
if (!lua_istable(L, index)) {
if (error_msg) luaL_argerror(L, index, error_msg);
return false;
}
bool all_match = true;
const int n = (int)lua_objlen(L, index);
for (int i = 0; i < n; ++i) {
lua_rawgeti(L, index, i + 1);
if(isType<T>(L, -1)) {
func(toType<T>(L, -1));
}
else if (error_msg) {
lua_pop(L, 1);
luaL_argerror(L, index, error_msg);
}
else {
all_match = false;
}
lua_pop(L, 1);
}
return all_match;
}
template <typename T> inline const char* typeToString() template <typename T> inline const char* typeToString()
{ {
@ -386,98 +472,6 @@ template <> inline const char* typeToString<float>()
return "number|float"; return "number|float";
} }
template <typename T> inline bool isType(lua_State* L, int index)
{
return lua_islightuserdata(L, index) != 0;
}
template <> inline bool isType<int>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<u16>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<Path>(lua_State* L, int index)
{
return lua_isstring(L, index);
}
template <> inline bool isType<u8>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<EntityRef>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<EntityPtr>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<ComponentType>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<Vec3>(lua_State* L, int index)
{
return lua_istable(L, index) != 0 && lua_objlen(L, index) == 3;
}
template <> inline bool isType<DVec3>(lua_State* L, int index)
{
return lua_istable(L, index) != 0 && lua_objlen(L, index) == 3;
}
template <> inline bool isType<Vec4>(lua_State* L, int index)
{
return lua_istable(L, index) != 0 && lua_objlen(L, index) == 4;
}
template <> inline bool isType<Vec2>(lua_State* L, int index)
{
return lua_istable(L, index) != 0 && lua_objlen(L, index) == 2;
}
template <> inline bool isType<Matrix>(lua_State* L, int index)
{
return lua_istable(L, index) != 0 && lua_objlen(L, index) == 16;
}
template <> inline bool isType<Quat>(lua_State* L, int index)
{
return lua_istable(L, index) != 0 && lua_objlen(L, index) == 4;
}
template <> inline bool isType<u32>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<u64>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<i64>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<bool>(lua_State* L, int index)
{
return lua_isboolean(L, index) != 0;
}
template <> inline bool isType<float>(lua_State* L, int index)
{
return lua_isnumber(L, index) != 0;
}
template <> inline bool isType<const char*>(lua_State* L, int index)
{
return lua_isstring(L, index) != 0;
}
template <> inline bool isType<void*>(lua_State* L, int index)
{
return lua_islightuserdata(L, index) != 0;
}
template <typename T> inline void setField(lua_State* L, int table_idx, const char* name, T value)
{
push(L, value);
lua_setfield(L, table_idx - 1, name);
}
template <typename T> inline void push(lua_State* L, T value) template <typename T> inline void push(lua_State* L, T value)
{ {
lua_pushlightuserdata(L, value); lua_pushlightuserdata(L, value);
@ -640,6 +634,11 @@ template <> inline void push(lua_State* L, void* value)
lua_pushlightuserdata(L, value); lua_pushlightuserdata(L, value);
} }
template <typename T> inline void setField(lua_State* L, int table_idx, const char* name, T value)
{
push(L, value);
lua_setfield(L, table_idx - 1, name);
}
inline void createSystemVariable(lua_State* L, const char* system, const char* var_name, void* value) inline void createSystemVariable(lua_State* L, const char* system, const char* var_name, void* value)
{ {

View file

@ -4,7 +4,7 @@
#include <signal.h> // SIGTRAP #include <signal.h> // SIGTRAP
#endif #endif
#ifndef _WIN32 #if !defined(_WIN32) && !defined(__linux__)
#error Platform not supported #error Platform not supported
#endif #endif

View file

@ -1,7 +1,9 @@
#include "math.h" #include "math.h"
#include "simd.h" #include "simd.h"
#include <random> #include <random>
#ifdef __linux__
#include <float.h>
#endif
namespace Lumix namespace Lumix
{ {

View file

@ -175,52 +175,5 @@ bool Event::poll()
} }
SpinMutex::SpinMutex(bool locked)
: m_id(0)
{
if (locked)
{
lock();
}
}
SpinMutex::~SpinMutex()
{
}
void SpinMutex::lock()
{
for (;;)
{
if (compareAndExchange(&m_id, 1, 0))
{
memoryBarrier();
return;
}
while (m_id)
{
yield();
}
}
}
bool SpinMutex::poll()
{
if (compareAndExchange(&m_id, 1, 0))
{
memoryBarrier();
return true;
}
return false;
}
void SpinMutex::unlock()
{
memoryBarrier();
m_id = 0;
}
} // namespace MT } // namespace MT
} // namespace Lumix } // namespace Lumix

View file

@ -1,5 +1,5 @@
#include "engine/allocator.h"
#include "engine/lumix.h" #include "engine/lumix.h"
#include "engine/iallocator.h"
#include "engine/mt/task.h" #include "engine/mt/task.h"
#include "engine/mt/thread.h" #include "engine/mt/thread.h"
#include "engine/profiler.h" #include "engine/profiler.h"
@ -55,7 +55,7 @@ Task::~Task()
LUMIX_DELETE(m_implementation->allocator, m_implementation); LUMIX_DELETE(m_implementation->allocator, m_implementation);
} }
bool Task::create(const char* name) bool Task::create(const char* name, bool is_extended)
{ {
pthread_attr_t attr; pthread_attr_t attr;
int res = pthread_attr_init(&attr); int res = pthread_attr_init(&attr);
@ -87,11 +87,6 @@ void Task::setAffinityMask(u64 affinity_mask)
pthread_setaffinity_np(m_implementation->handle, sizeof(set), &set); pthread_setaffinity_np(m_implementation->handle, sizeof(set), &set);
} }
u64 Task::getAffinityMask() const
{
return m_implementation->affinity_mask;
}
bool Task::isRunning() const bool Task::isRunning() const
{ {
return m_implementation->is_running; return m_implementation->is_running;
@ -102,26 +97,11 @@ bool Task::isFinished() const
return m_implementation->exited; return m_implementation->exited;
} }
bool Task::isForceExit() const
{
return m_implementation->force_exit;
}
IAllocator& Task::getAllocator() IAllocator& Task::getAllocator()
{ {
return m_implementation->allocator; return m_implementation->allocator;
} }
void Task::forceExit(bool wait)
{
m_implementation->force_exit = true;
if (wait)
{
pthread_join(m_implementation->handle, nullptr);
}
}
} // namespace MT } // namespace MT
} // namespace Lumix } // namespace Lumix

View file

@ -1,8 +1,9 @@
#define INITGUID #ifdef _WIN32
#define NOGDI #define INITGUID
#include <Windows.h> #define NOGDI
#include <evntcons.h> #include <Windows.h>
#include <evntcons.h>
#endif
#include "engine/array.h" #include "engine/array.h"
#include "engine/crt.h" #include "engine/crt.h"
@ -46,44 +47,52 @@ struct ThreadContext
u32 thread_id; u32 thread_id;
}; };
#define SWITCH_CONTEXT_OPCODE 36 #ifdef _WIN32
#define SWITCH_CONTEXT_OPCODE 36
#pragma pack(1) #pragma pack(1)
struct TraceProps struct TraceProps
{
EVENT_TRACE_PROPERTIES base;
char name[sizeof(KERNEL_LOGGER_NAME) + 1];
};
#pragma pack()
// https://docs.microsoft.com/en-us/windows/desktop/etw/cswitch
struct CSwitch
{ {
EVENT_TRACE_PROPERTIES base; u32 NewThreadId;
char name[sizeof(KERNEL_LOGGER_NAME) + 1]; u32 OldThreadId;
i8 NewThreadPriority;
i8 OldThreadPriority;
u8 PreviousCState;
i8 SpareByte;
i8 OldThreadWaitReason;
i8 OldThreadWaitMode;
i8 OldThreadState;
i8 OldThreadWaitIdealProcessor;
u32 NewThreadWaitTime;
u32 Reserved;
}; };
#pragma pack()
// https://docs.microsoft.com/en-us/windows/desktop/etw/cswitch struct TraceTask : MT::Task {
struct CSwitch TraceTask(IAllocator& allocator);
{
u32 NewThreadId;
u32 OldThreadId;
i8 NewThreadPriority;
i8 OldThreadPriority;
u8 PreviousCState;
i8 SpareByte;
i8 OldThreadWaitReason;
i8 OldThreadWaitMode;
i8 OldThreadState;
i8 OldThreadWaitIdealProcessor;
u32 NewThreadWaitTime;
u32 Reserved;
};
int task() override;
static void callback(PEVENT_RECORD event);
struct TraceTask : MT::Task { TRACEHANDLE open_handle;
TraceTask(IAllocator& allocator); };
#else
int task() override; struct TraceTask {
static void callback(PEVENT_RECORD event); TraceTask(IAllocator&) {}
void destroy() {}
TRACEHANDLE open_handle; int open_handle;
}; };
void CloseTrace(int) {}
#endif
static struct Instance static struct Instance
{ {
@ -105,38 +114,40 @@ static struct Instance
void startTrace() void startTrace()
{ {
static TRACEHANDLE trace_handle; #ifdef _WIN32
static TraceProps props = {}; static TRACEHANDLE trace_handle;
props.base.Wnode.BufferSize = sizeof(props); static TraceProps props = {};
props.base.Wnode.Flags = WNODE_FLAG_TRACED_GUID; props.base.Wnode.BufferSize = sizeof(props);
props.base.Wnode.ClientContext = 1; props.base.Wnode.Flags = WNODE_FLAG_TRACED_GUID;
props.base.Wnode.Guid = SystemTraceControlGuid; props.base.Wnode.ClientContext = 1;
props.base.LoggerNameOffset = sizeof(props.base); props.base.Wnode.Guid = SystemTraceControlGuid;
props.base.EnableFlags = EVENT_TRACE_FLAG_CSWITCH; props.base.LoggerNameOffset = sizeof(props.base);
props.base.LogFileMode = EVENT_TRACE_REAL_TIME_MODE; props.base.EnableFlags = EVENT_TRACE_FLAG_CSWITCH;
strcpy_s(props.name, KERNEL_LOGGER_NAME); props.base.LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
strcpy_s(props.name, KERNEL_LOGGER_NAME);
TraceProps tmp = props; TraceProps tmp = props;
ControlTrace(NULL, KERNEL_LOGGER_NAME, &tmp.base, EVENT_TRACE_CONTROL_STOP); ControlTrace(NULL, KERNEL_LOGGER_NAME, &tmp.base, EVENT_TRACE_CONTROL_STOP);
ULONG res = StartTrace(&trace_handle, KERNEL_LOGGER_NAME, &props.base); ULONG res = StartTrace(&trace_handle, KERNEL_LOGGER_NAME, &props.base);
switch (res) { switch (res) {
case ERROR_ALREADY_EXISTS: case ERROR_ALREADY_EXISTS:
case ERROR_ACCESS_DENIED: case ERROR_ACCESS_DENIED:
case ERROR_BAD_LENGTH: case ERROR_BAD_LENGTH:
default: default:
context_switches_enabled = false; context_switches_enabled = false;
break; break;
case ERROR_SUCCESS: case ERROR_SUCCESS:
context_switches_enabled = true; context_switches_enabled = true;
break; break;
} }
static EVENT_TRACE_LOGFILE trace = {}; static EVENT_TRACE_LOGFILE trace = {};
trace.LoggerName = KERNEL_LOGGER_NAME; trace.LoggerName = KERNEL_LOGGER_NAME;
trace.ProcessTraceMode = PROCESS_TRACE_MODE_RAW_TIMESTAMP | PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD | PROCESS_TRACE_MODE_RAW_TIMESTAMP; trace.ProcessTraceMode = PROCESS_TRACE_MODE_RAW_TIMESTAMP | PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD | PROCESS_TRACE_MODE_RAW_TIMESTAMP;
trace.EventRecordCallback = TraceTask::callback; trace.EventRecordCallback = TraceTask::callback;
trace_task.open_handle = OpenTrace(&trace); trace_task.open_handle = OpenTrace(&trace);
trace_task.create("Profiler trace", true); trace_task.create("Profiler trace", true);
#endif
} }
@ -280,31 +291,31 @@ void write(ThreadContext& ctx, EventType type, const u8* data, int size)
cpy(data, size); cpy(data, size);
}; };
#ifdef _WIN32
TraceTask::TraceTask(IAllocator& allocator) TraceTask::TraceTask(IAllocator& allocator)
: MT::Task(allocator) : MT::Task(allocator)
{} {}
int TraceTask::task() { int TraceTask::task() {
ProcessTrace(&open_handle, 1, nullptr, nullptr); ProcessTrace(&open_handle, 1, nullptr, nullptr);
return 0; return 0;
} }
void TraceTask::callback(PEVENT_RECORD event) { void TraceTask::callback(PEVENT_RECORD event) {
if (event->EventHeader.EventDescriptor.Opcode != SWITCH_CONTEXT_OPCODE) return; if (event->EventHeader.EventDescriptor.Opcode != SWITCH_CONTEXT_OPCODE) return;
if (sizeof(CSwitch) != event->UserDataLength) return; if (sizeof(CSwitch) != event->UserDataLength) return;
const CSwitch* cs = reinterpret_cast<CSwitch*>(event->UserData);
ContextSwitchRecord rec;
rec.timestamp = event->EventHeader.TimeStamp.QuadPart;
rec.new_thread_id = cs->NewThreadId;
rec.old_thread_id = cs->OldThreadId;
rec.reason = cs->OldThreadWaitReason;
write(g_instance.global_context, rec.timestamp, Profiler::EventType::CONTEXT_SWITCH, rec);
};
const CSwitch* cs = reinterpret_cast<CSwitch*>(event->UserData);
ContextSwitchRecord rec;
rec.timestamp = event->EventHeader.TimeStamp.QuadPart;
rec.new_thread_id = cs->NewThreadId;
rec.old_thread_id = cs->OldThreadId;
rec.reason = cs->OldThreadWaitReason;
write(g_instance.global_context, rec.timestamp, Profiler::EventType::CONTEXT_SWITCH, rec);
};
#endif
void pushInt(const char* key, int value) void pushInt(const char* key, int value)
{ {

View file

@ -39,16 +39,6 @@ namespace Lumix
Iterator begin() { return {this, m_rd}; } Iterator begin() { return {this, m_rd}; }
Iterator end() { return {this, m_wr}; } Iterator end() { return {this, m_wr}; }
T& emplace()
{
ASSERT(m_wr - m_rd < count);
u32 idx = m_wr & (count - 1);
T& res = ::new (NewPlaceholder(), &m_buffer[idx]) T(item);
++m_wr;
return res;
}
void push(const T& item) void push(const T& item)
{ {
ASSERT(m_wr - m_rd < count); ASSERT(m_wr - m_rd < count);

View file

@ -1,6 +1,5 @@
#pragma once #pragma once
#define PASCAL __stdcall #define PASCAL __stdcall
#ifndef _W64 #ifndef _W64
#define _W64 __w64 #define _W64 __w64

View file

@ -665,7 +665,8 @@ namespace Lumix
if (!isSameProperty(prop.name, prop_name)) return; if (!isSameProperty(prop.name, prop_name)) return;
T val; T val;
prop.getValue(cmp, idx, OutputMemoryStream(&val, sizeof(val))); OutputMemoryStream blob(&val, sizeof(val));
prop.getValue(cmp, idx, blob);
count = 1; count = 1;
LuaWrapper::push(L, val); LuaWrapper::push(L, val);
} }
@ -684,7 +685,8 @@ namespace Lumix
if (!isSameProperty(prop.name, prop_name)) return; if (!isSameProperty(prop.name, prop_name)) return;
char tmp[MAX_PATH_LENGTH]; char tmp[MAX_PATH_LENGTH];
prop.getValue(cmp, idx, OutputMemoryStream(tmp, sizeof(tmp))); OutputMemoryStream blob(tmp, sizeof(tmp));
prop.getValue(cmp, idx, blob);
count = 1; count = 1;
LuaWrapper::push(L, tmp); LuaWrapper::push(L, tmp);
} }
@ -693,7 +695,8 @@ namespace Lumix
if (!isSameProperty(prop.name, prop_name)) return; if (!isSameProperty(prop.name, prop_name)) return;
char tmp[1024]; char tmp[1024];
prop.getValue(cmp, idx, OutputMemoryStream(tmp, sizeof(tmp))); OutputMemoryStream blob(tmp, sizeof(tmp));
prop.getValue(cmp, idx, blob);
count = 1; count = 1;
LuaWrapper::push(L, tmp); LuaWrapper::push(L, tmp);
} }
@ -728,7 +731,8 @@ namespace Lumix
if (!isSameProperty(prop.name, prop_name)) return; if (!isSameProperty(prop.name, prop_name)) return;
const T val = LuaWrapper::toType<T>(L, 3); const T val = LuaWrapper::toType<T>(L, 3);
prop.setValue(cmp, idx, InputMemoryStream(&val, sizeof(val))); InputMemoryStream blob(&val, sizeof(val));
prop.setValue(cmp, idx, blob);
} }
void visit(const Reflection::Property<float>& prop) override { set(prop); } void visit(const Reflection::Property<float>& prop) override { set(prop); }
@ -745,14 +749,16 @@ namespace Lumix
if (!isSameProperty(prop.name, prop_name)) return; if (!isSameProperty(prop.name, prop_name)) return;
const char* val = LuaWrapper::toType<const char*>(L, 3); const char* val = LuaWrapper::toType<const char*>(L, 3);
prop.setValue(cmp, idx, InputMemoryStream(val, 1 + stringLength(val))); InputMemoryStream blob(val, 1 + stringLength(val));
prop.setValue(cmp, idx, blob);
} }
void visit(const Reflection::Property<const char*>& prop) override { void visit(const Reflection::Property<const char*>& prop) override {
if (!isSameProperty(prop.name, prop_name)) return; if (!isSameProperty(prop.name, prop_name)) return;
const char* val = LuaWrapper::toType<const char*>(L, 3); const char* val = LuaWrapper::toType<const char*>(L, 3);
prop.setValue(cmp, idx, InputMemoryStream(val, 1 + stringLength(val))); InputMemoryStream blob(val, 1 + stringLength(val));
prop.setValue(cmp, idx, blob);
} }
void visit(const Reflection::IArrayProperty& prop) override {} void visit(const Reflection::IArrayProperty& prop) override {}

View file

@ -4,6 +4,7 @@
#include "engine/associative_array.h" #include "engine/associative_array.h"
#include "engine/crc32.h" #include "engine/crc32.h"
#include "engine/engine.h" #include "engine/engine.h"
#include "engine/mt/atomic.h"
#include "engine/job_system.h" #include "engine/job_system.h"
#include "engine/log.h" #include "engine/log.h"
#include "engine/lua_wrapper.h" #include "engine/lua_wrapper.h"

View file

@ -4,10 +4,10 @@
#include "engine/geometry.h" #include "engine/geometry.h"
#include "engine/hash_map.h" #include "engine/hash_map.h"
#include "engine/allocator.h" #include "engine/allocator.h"
#include "engine/mt/atomic.h"
#include "engine/job_system.h" #include "engine/job_system.h"
#include "engine/lumix.h" #include "engine/lumix.h"
#include "engine/math.h" #include "engine/math.h"
#include "engine/mt/atomic.h"
#include "engine/mt/thread.h" #include "engine/mt/thread.h"
#include "engine/page_allocator.h" #include "engine/page_allocator.h"
#include "engine/profiler.h" #include "engine/profiler.h"

View file

@ -8,8 +8,13 @@ namespace ofbx
typedef unsigned char u8; typedef unsigned char u8;
typedef unsigned short u16; typedef unsigned short u16;
typedef unsigned int u32; typedef unsigned int u32;
typedef unsigned long long u64; #ifdef _WIN32
typedef long long i64; typedef unsigned long long u64;
typedef long long i64;
#else
typedef unsigned long u64;
typedef long i64;
#endif
static_assert(sizeof(u8) == 1, "u8 is not 1 byte"); static_assert(sizeof(u8) == 1, "u8 is not 1 byte");
static_assert(sizeof(u32) == 4, "u32 is not 4 bytes"); static_assert(sizeof(u32) == 4, "u32 is not 4 bytes");

View file

@ -13,11 +13,11 @@
#include "engine/engine.h" #include "engine/engine.h"
#include "engine/file_system.h" #include "engine/file_system.h"
#include "engine/geometry.h" #include "engine/geometry.h"
#include "engine/mt/atomic.h"
#include "engine/job_system.h" #include "engine/job_system.h"
#include "engine/log.h" #include "engine/log.h"
#include "engine/lua_wrapper.h" #include "engine/lua_wrapper.h"
#include "engine/lumix.h" #include "engine/lumix.h"
#include "engine/mt/atomic.h"
#include "engine/mt/thread.h" #include "engine/mt/thread.h"
#include "engine/os.h" #include "engine/os.h"
#include "engine/path_utils.h" #include "engine/path_utils.h"

View file

@ -5,11 +5,25 @@
#include "engine/log.h" #include "engine/log.h"
#include "engine/math.h" #include "engine/math.h"
#include "engine/mt/sync.h" #include "engine/mt/sync.h"
#include "engine/mt/thread.h"
#include "engine/os.h"
#include "engine/stream.h" #include "engine/stream.h"
#include <Windows.h> #ifdef _WIN32
#include <gl/GL.h> #include <Windows.h>
#endif
#ifdef __linux__
#include <X11/Xlib.h>
#define GLX_GLXEXT_LEGACY
#include <GL/glx.h>
#include <GL/glxext.h>
#endif
#include <GL/gl.h>
#include "renderdoc_app.h" #include "renderdoc_app.h"
namespace Lumix {
namespace gpu {
#define GPU_GL_IMPORT(prototype, name) static prototype name; #define GPU_GL_IMPORT(prototype, name) static prototype name;
#define GPU_GL_IMPORT_TYPEDEFS #define GPU_GL_IMPORT_TYPEDEFS
@ -18,13 +32,6 @@
#undef GPU_GL_IMPORT_TYPEDEFS #undef GPU_GL_IMPORT_TYPEDEFS
#undef GPU_GL_IMPORT #undef GPU_GL_IMPORT
namespace Lumix
{
namespace gpu {
struct Buffer struct Buffer
{ {
enum { MAX_COUNT = 8192 }; enum { MAX_COUNT = 8192 };
@ -94,9 +101,11 @@ struct Pool
struct WindowContext { struct WindowContext {
void* window_handle = nullptr; void* window_handle = nullptr;
GLuint vao;
#ifdef _WIN32
HDC device_context; HDC device_context;
HGLRC hglrc; HGLRC hglrc;
GLuint vao; #endif
}; };
static struct { static struct {
@ -107,7 +116,7 @@ static struct {
Pool<Texture, Texture::MAX_COUNT> textures; Pool<Texture, Texture::MAX_COUNT> textures;
Pool<Program, Program::MAX_COUNT> programs; Pool<Program, Program::MAX_COUNT> programs;
MT::CriticalSection handle_mutex; MT::CriticalSection handle_mutex;
DWORD thread; Lumix::MT::ThreadID thread;
int instance_attributes = 0; int instance_attributes = 0;
int max_vertex_attributes = 16; int max_vertex_attributes = 16;
ProgramHandle last_program = INVALID_PROGRAM; ProgramHandle last_program = INVALID_PROGRAM;
@ -704,20 +713,22 @@ static void flipCompressedTexture(int w, int h, int format, void* surface)
void checkThread() void checkThread()
{ {
ASSERT(g_gpu.thread == GetCurrentThreadId()); ASSERT(g_gpu.thread == Lumix::MT::getCurrentThreadID());
} }
static void try_load_renderdoc() static void try_load_renderdoc()
{ {
HMODULE lib = LoadLibrary("renderdoc.dll"); #ifdef _WIN32
if (!lib) return; void* lib = OS::loadLibrary("renderdoc.dll");
pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)GetProcAddress(lib, "RENDERDOC_GetAPI"); if (!lib) return;
if (RENDERDOC_GetAPI) { pRENDERDOC_GetAPI RENDERDOC_GetAPI = (pRENDERDOC_GetAPI)OS::getLibrarySymbol(lib, "RENDERDOC_GetAPI");
RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_0_2, (void **)&g_gpu.rdoc_api); if (RENDERDOC_GetAPI) {
g_gpu.rdoc_api->MaskOverlayBits(~RENDERDOC_OverlayBits::eRENDERDOC_Overlay_Enabled, 0); RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_0_2, (void **)&g_gpu.rdoc_api);
} g_gpu.rdoc_api->MaskOverlayBits(~RENDERDOC_OverlayBits::eRENDERDOC_Overlay_Enabled, 0);
/**/ }
//FreeLibrary(lib); /**/
//FreeLibrary(lib);
#endif
} }
static void logVersion() { static void logVersion() {
@ -729,94 +740,103 @@ static void logVersion() {
logInfo("Renderer") << "OpenGL renderer: " << renderer; logInfo("Renderer") << "OpenGL renderer: " << renderer;
} }
static void* getGLFunc(const char* name) {
#ifdef _WIN32
return wglGetProcAddress(name);
#else
return (void*)glXGetProcAddress((const GLubyte*)name);
#endif
}
static bool load_gl(void* device_contex, u32 init_flags) static bool load_gl(void* device_contex, u32 init_flags)
{ {
const bool vsync = init_flags & (u32)InitFlags::VSYNC; const bool vsync = init_flags & (u32)InitFlags::VSYNC;
HDC hdc = (HDC)device_contex; #ifdef _WIN32
const PIXELFORMATDESCRIPTOR pfd = HDC hdc = (HDC)device_contex;
{ const PIXELFORMATDESCRIPTOR pfd =
sizeof(PIXELFORMATDESCRIPTOR), {
1, sizeof(PIXELFORMATDESCRIPTOR),
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags 1,
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette. PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags
32, // Colordepth of the framebuffer. PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
0, 0, 0, 0, 0, 0, 32, // Colordepth of the framebuffer.
0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0,
0, 0, 0, 0, 0,
24, // Number of bits for the depthbuffer 0, 0, 0, 0,
8, // Number of bits for the stencilbuffer 24, // Number of bits for the depthbuffer
0, // Number of Aux buffers in the framebuffer. 8, // Number of bits for the stencilbuffer
PFD_MAIN_PLANE, 0, // Number of Aux buffers in the framebuffer.
0, PFD_MAIN_PLANE,
0, 0, 0 0,
}; 0, 0, 0
const int pf = ChoosePixelFormat(hdc, &pfd); };
BOOL pf_status = SetPixelFormat(hdc, pf, &pfd); const int pf = ChoosePixelFormat(hdc, &pfd);
ASSERT(pf_status == TRUE); BOOL pf_status = SetPixelFormat(hdc, pf, &pfd);
ASSERT(pf_status == TRUE);
const HGLRC dummy_context = wglCreateContext(hdc); const HGLRC dummy_context = wglCreateContext(hdc);
ASSERT(dummy_context); ASSERT(dummy_context);
wglMakeCurrent(hdc, dummy_context); wglMakeCurrent(hdc, dummy_context);
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList); typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)getGLFunc("wglCreateContextAttribsARB");
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)getGLFunc("wglSwapIntervalEXT");
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 #define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
#define WGL_CONTEXT_FLAGS_ARB 0x2094 #define WGL_CONTEXT_FLAGS_ARB 0x2094
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
const int32_t contextAttrs[] = { const int32_t contextAttrs[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 4, WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, 5, WGL_CONTEXT_MINOR_VERSION_ARB, 5,
#ifdef LUMIX_DEBUG #ifdef LUMIX_DEBUG
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
#endif #endif
// WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB , // WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB ,
0 0
}; };
HGLRC hglrc = wglCreateContextAttribsARB(hdc, 0, contextAttrs); HGLRC hglrc = wglCreateContextAttribsARB(hdc, 0, contextAttrs);
if (hglrc) { if (hglrc) {
wglMakeCurrent(hdc, hglrc); wglMakeCurrent(hdc, hglrc);
wglDeleteContext(dummy_context); wglDeleteContext(dummy_context);
} }
else { else {
DWORD err = GetLastError(); DWORD err = GetLastError();
logError("Renderer") << "wglCreateContextAttribsARB failed, GetLastError() = " << (u32) err; logError("Renderer") << "wglCreateContextAttribsARB failed, GetLastError() = " << (u32) err;
logError("Renderer") << "OpenGL 4.5+ required"; logError("Renderer") << "OpenGL 4.5+ required";
logVersion();
return false;
}
logVersion(); logVersion();
return false; g_gpu.contexts[0].hglrc = hglrc;
} wglSwapIntervalEXT(vsync ? 1 : 0);
logVersion(); void* gl_dll = OS::loadLibrary("opengl32.dll");
g_gpu.contexts[0].hglrc = hglrc;
wglSwapIntervalEXT(vsync ? 1 : 0);
HMODULE gl_dll = LoadLibrary("opengl32.dll");
#define GPU_GL_IMPORT(prototype, name) \ #define GPU_GL_IMPORT(prototype, name) \
do { \ do { \
name = (prototype)wglGetProcAddress(#name); \ name = (prototype)getGLFunc(#name); \
if (!name && gl_dll) { \ if (!name && gl_dll) { \
name = (prototype)GetProcAddress(gl_dll, #name); \ name = (prototype)OS::getLibrarySymbol(gl_dll, #name); \
if (!name) { \ if (!name) { \
logError("Renderer") << "Failed to load GL function " #name "."; \ logError("Renderer") << "Failed to load GL function " #name "."; \
return false; \ return false; \
} \
} \ } \
} \ } while(0)
} while(0)
#include "gl_ext.h" #include "gl_ext.h"
#undef GPU_GL_IMPORT
#undef GPU_GL_IMPORT
#endif
return true; return true;
} }
@ -1225,96 +1245,98 @@ static void gl_debug_callback(GLenum source, GLenum type, GLuint id, GLenum seve
void setCurrentWindow(void* window_handle) { void setCurrentWindow(void* window_handle) {
checkThread(); checkThread();
WindowContext& ctx = [window_handle]() -> WindowContext& { #ifdef _WIN32
if (!window_handle) return g_gpu.contexts[0]; WindowContext& ctx = [window_handle]() -> WindowContext& {
if (!window_handle) return g_gpu.contexts[0];
for (WindowContext& i : g_gpu.contexts) { for (WindowContext& i : g_gpu.contexts) {
if (i.window_handle == window_handle) return i; if (i.window_handle == window_handle) return i;
}
for (WindowContext& i : g_gpu.contexts) {
if (!i.window_handle) {
i.window_handle = window_handle;
i.device_context = GetDC((HWND)window_handle);
i.hglrc = 0;
return i;
} }
}
LUMIX_FATAL(false);
return g_gpu.contexts[0];
}();
if (!ctx.hglrc) { for (WindowContext& i : g_gpu.contexts) {
const HDC hdc = ctx.device_context; if (!i.window_handle) {
const PIXELFORMATDESCRIPTOR pfd = i.window_handle = window_handle;
{ i.device_context = GetDC((HWND)window_handle);
sizeof(PIXELFORMATDESCRIPTOR), i.hglrc = 0;
1, return i;
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags }
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette. }
32, // Colordepth of the framebuffer. LUMIX_FATAL(false);
0, 0, 0, 0, 0, 0, return g_gpu.contexts[0];
0, }();
0,
0,
0, 0, 0, 0,
24, // Number of bits for the depthbuffer
8, // Number of bits for the stencilbuffer
0, // Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};
const int pf = ChoosePixelFormat(hdc, &pfd);
BOOL pf_status = SetPixelFormat(hdc, pf, &pfd);
ASSERT(pf_status == TRUE);
wglMakeCurrent(hdc, g_gpu.contexts[0].hglrc); if (!ctx.hglrc) {
const HDC hdc = ctx.device_context;
const PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
32, // Colordepth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, // Number of bits for the depthbuffer
8, // Number of bits for the stencilbuffer
0, // Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};
const int pf = ChoosePixelFormat(hdc, &pfd);
BOOL pf_status = SetPixelFormat(hdc, pf, &pfd);
ASSERT(pf_status == TRUE);
wglMakeCurrent(hdc, g_gpu.contexts[0].hglrc);
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)getGLFunc("wglCreateContextAttribsARB");
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)getGLFunc("wglSwapIntervalEXT");
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
const int32_t contextAttrs[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, 5,
#ifdef LUMIX_DEBUG
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
#endif
// WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB ,
0
};
// TODO destroy context when window is destroyed
HGLRC hglrc = wglCreateContextAttribsARB(hdc, g_gpu.contexts[0].hglrc, contextAttrs);
ctx.hglrc = hglrc;
wglMakeCurrent(ctx.device_context, hglrc);
CHECK_GL(glGenVertexArrays(1, &ctx.vao));
CHECK_GL(glBindVertexArray(ctx.vao));
CHECK_GL(glVertexBindingDivisor(0, 0));
CHECK_GL(glVertexBindingDivisor(1, 1));
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
const int32_t contextAttrs[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, 5,
#ifdef LUMIX_DEBUG #ifdef LUMIX_DEBUG
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, CHECK_GL(glEnable(GL_DEBUG_OUTPUT));
CHECK_GL(glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS));
CHECK_GL(glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE));
CHECK_GL(glDebugMessageCallback(gl_debug_callback, 0));
#endif #endif
// WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB ,
0
};
// TODO destroy context when window is destroyed }
HGLRC hglrc = wglCreateContextAttribsARB(hdc, g_gpu.contexts[0].hglrc, contextAttrs);
ctx.hglrc = hglrc;
wglMakeCurrent(ctx.device_context, hglrc);
CHECK_GL(glGenVertexArrays(1, &ctx.vao));
CHECK_GL(glBindVertexArray(ctx.vao));
CHECK_GL(glVertexBindingDivisor(0, 0));
CHECK_GL(glVertexBindingDivisor(1, 1));
#ifdef LUMIX_DEBUG wglMakeCurrent(ctx.device_context, ctx.hglrc);
CHECK_GL(glEnable(GL_DEBUG_OUTPUT)); #endif
CHECK_GL(glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS));
CHECK_GL(glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE));
CHECK_GL(glDebugMessageCallback(gl_debug_callback, 0));
#endif
}
wglMakeCurrent(ctx.device_context, ctx.hglrc);
useProgram(INVALID_PROGRAM); useProgram(INVALID_PROGRAM);
} }
@ -1324,7 +1346,9 @@ void swapBuffers()
checkThread(); checkThread();
glFinish(); glFinish();
for (const WindowContext& ctx : g_gpu.contexts) { for (const WindowContext& ctx : g_gpu.contexts) {
SwapBuffers(ctx.device_context); #ifdef _WIN32
SwapBuffers(ctx.device_context);
#endif
} }
} }
@ -1979,61 +2003,62 @@ bool init(void* window_handle, u32 init_flags)
#else #else
const bool debug = init_flags & (u32)InitFlags::DEBUG_OUTPUT; const bool debug = init_flags & (u32)InitFlags::DEBUG_OUTPUT;
#endif #endif
g_gpu.contexts[0].window_handle = window_handle;
g_gpu.contexts[0].device_context = GetDC((HWND)window_handle);
g_gpu.thread = GetCurrentThreadId();
if (!load_gl(g_gpu.contexts[0].device_context, init_flags)) return false;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &g_gpu.max_vertex_attributes);
int extensions_count;
glGetIntegerv(GL_NUM_EXTENSIONS, &extensions_count);
g_gpu.has_gpu_mem_info_ext = false;
for(int i = 0; i < extensions_count; ++i) {
const char* ext = (const char*)glGetStringi(GL_EXTENSIONS, i);
if (equalStrings(ext, "GL_NVX_gpu_memory_info")) {
g_gpu.has_gpu_mem_info_ext = true;
break;
}
//OutputDebugString(ext);
//OutputDebugString("\n");
}
//const unsigned char* version = glGetString(GL_VERSION);
CHECK_GL(glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE));
CHECK_GL(glDepthFunc(GL_GREATER));
if (debug) {
CHECK_GL(glEnable(GL_DEBUG_OUTPUT));
CHECK_GL(glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS));
CHECK_GL(glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE));
CHECK_GL(glDebugMessageCallback(gl_debug_callback, 0));
}
CHECK_GL(glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS));
CHECK_GL(glBindVertexArray(0));
CHECK_GL(glCreateFramebuffers(1, &g_gpu.framebuffer));
g_gpu.default_program = allocProgramHandle(); #ifdef _WIN32
Program& p = g_gpu.programs[g_gpu.default_program.value]; g_gpu.contexts[0].window_handle = window_handle;
p.handle = glCreateProgram(); g_gpu.contexts[0].device_context = GetDC((HWND)window_handle);
CHECK_GL(glGenVertexArrays(1, &g_gpu.contexts[0].vao)); g_gpu.thread = GetCurrentThreadId();
CHECK_GL(glBindVertexArray(g_gpu.contexts[0].vao));
CHECK_GL(glVertexBindingDivisor(0, 0));
CHECK_GL(glVertexBindingDivisor(1, 1));
const GLuint vs = glCreateShader(GL_VERTEX_SHADER); if (!load_gl(g_gpu.contexts[0].device_context, init_flags)) return false;
const char* vs_src = "void main() { gl_Position = vec4(0, 0, 0, 0); }";
glShaderSource(vs, 1, &vs_src, nullptr);
glCompileShader(vs);
glAttachShader(p.handle, vs);
CHECK_GL(glLinkProgram(p.handle));
glDeleteShader(vs);
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &g_gpu.max_vertex_attributes);
int extensions_count;
glGetIntegerv(GL_NUM_EXTENSIONS, &extensions_count);
g_gpu.has_gpu_mem_info_ext = false;
for(int i = 0; i < extensions_count; ++i) {
const char* ext = (const char*)glGetStringi(GL_EXTENSIONS, i);
if (equalStrings(ext, "GL_NVX_gpu_memory_info")) {
g_gpu.has_gpu_mem_info_ext = true;
break;
}
//OutputDebugString(ext);
//OutputDebugString("\n");
}
//const unsigned char* version = glGetString(GL_VERSION);
CHECK_GL(glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE));
CHECK_GL(glDepthFunc(GL_GREATER));
if (debug) {
CHECK_GL(glEnable(GL_DEBUG_OUTPUT));
CHECK_GL(glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS));
CHECK_GL(glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE));
CHECK_GL(glDebugMessageCallback(gl_debug_callback, 0));
}
CHECK_GL(glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS));
CHECK_GL(glBindVertexArray(0));
CHECK_GL(glCreateFramebuffers(1, &g_gpu.framebuffer));
g_gpu.default_program = allocProgramHandle();
Program& p = g_gpu.programs[g_gpu.default_program.value];
p.handle = glCreateProgram();
CHECK_GL(glGenVertexArrays(1, &g_gpu.contexts[0].vao));
CHECK_GL(glBindVertexArray(g_gpu.contexts[0].vao));
CHECK_GL(glVertexBindingDivisor(0, 0));
CHECK_GL(glVertexBindingDivisor(1, 1));
const GLuint vs = glCreateShader(GL_VERTEX_SHADER);
const char* vs_src = "void main() { gl_Position = vec4(0, 0, 0, 0); }";
glShaderSource(vs, 1, &vs_src, nullptr);
glCompileShader(vs);
glAttachShader(p.handle, vs);
CHECK_GL(glLinkProgram(p.handle));
glDeleteShader(vs);
#endif
g_gpu.last_state = 1; g_gpu.last_state = 1;
setState(0); setState(0);

View file

@ -1,10 +1,10 @@
#include "particle_system.h" #include "particle_system.h"
#include "engine/crc32.h" #include "engine/crc32.h"
#include "engine/crt.h" #include "engine/crt.h"
#include "engine/mt/atomic.h"
#include "engine/job_system.h" #include "engine/job_system.h"
#include "engine/lua_wrapper.h" #include "engine/lua_wrapper.h"
#include "engine/math.h" #include "engine/math.h"
#include "engine/mt/atomic.h"
#include "engine/profiler.h" #include "engine/profiler.h"
#include "engine/reflection.h" #include "engine/reflection.h"
#include "engine/resource_manager.h" #include "engine/resource_manager.h"

View file

@ -5,11 +5,11 @@
#include "engine/engine.h" #include "engine/engine.h"
#include "engine/file_system.h" #include "engine/file_system.h"
#include "engine/geometry.h" #include "engine/geometry.h"
#include "engine/mt/atomic.h"
#include "engine/job_system.h" #include "engine/job_system.h"
#include "engine/log.h" #include "engine/log.h"
#include "engine/lua_wrapper.h" #include "engine/lua_wrapper.h"
#include "engine/math.h" #include "engine/math.h"
#include "engine/mt/atomic.h"
#include "engine/mt/sync.h" #include "engine/mt/sync.h"
#include "engine/os.h" #include "engine/os.h"
#include "engine/page_allocator.h" #include "engine/page_allocator.h"

View file

@ -7,7 +7,6 @@
#include "engine/engine.h" #include "engine/engine.h"
#include "engine/file_system.h" #include "engine/file_system.h"
#include "engine/geometry.h" #include "engine/geometry.h"
#include "engine/job_system.h"
#include "engine/log.h" #include "engine/log.h"
#include "engine/lua_wrapper.h" #include "engine/lua_wrapper.h"
#include "engine/math.h" #include "engine/math.h"

View file

@ -6,8 +6,8 @@
#include "engine/debug.h" #include "engine/debug.h"
#include "engine/engine.h" #include "engine/engine.h"
#include "engine/log.h" #include "engine/log.h"
#include "engine/job_system.h"
#include "engine/mt/atomic.h" #include "engine/mt/atomic.h"
#include "engine/job_system.h"
#include "engine/mt/sync.h" #include "engine/mt/sync.h"
#include "engine/mt/task.h" #include "engine/mt/task.h"
#include "engine/mt/thread.h" #include "engine/mt/thread.h"