compilable (not linkable yet) on linux
This commit is contained in:
parent
1c00f5e031
commit
963be7a0f2
38 changed files with 656 additions and 772 deletions
BIN
projects/genie
Executable file
BIN
projects/genie
Executable file
Binary file not shown.
|
@ -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.
|
@ -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"
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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);
|
||||||
|
|
152
src/engine/crt.h
152
src/engine/crt.h
|
@ -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
|
|
@ -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"
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
#include "engine/allocator.h"
|
||||||
#include "engine/controller_device.h"
|
#include "engine/controller_device.h"
|
||||||
#include "engine/iallocator.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
#define PASCAL __stdcall
|
#define PASCAL __stdcall
|
||||||
#ifndef _W64
|
#ifndef _W64
|
||||||
#define _W64 __w64
|
#define _W64 __w64
|
||||||
|
|
|
@ -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 {}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in a new issue