mirror of https://github.com/bjornbytes/lovr.git
Merge branch 'master' into dev
This commit is contained in:
commit
b6d8546a6f
|
@ -26,6 +26,7 @@ jobs:
|
|||
name: lovr.exe
|
||||
path: |
|
||||
build/Release/lovr.exe
|
||||
build/Release/lovrc.bat
|
||||
build/Release/*.dll
|
||||
linux:
|
||||
name: Linux
|
||||
|
|
|
@ -59,6 +59,8 @@ if(EMSCRIPTEN)
|
|||
set(LOVR_USE_OPENXR OFF)
|
||||
set(LOVR_USE_WEBGPU ON)
|
||||
set(LOVR_USE_VULKAN OFF)
|
||||
elseif(MSVC)
|
||||
add_compile_options(/MP)
|
||||
elseif(ANDROID)
|
||||
find_package(Java REQUIRED)
|
||||
set(LOVR_USE_DESKTOP OFF)
|
||||
|
@ -110,6 +112,11 @@ if(LOVR_USE_LUAJIT AND NOT EMSCRIPTEN)
|
|||
else()
|
||||
add_subdirectory(deps/luajit luajit)
|
||||
set_target_properties(luajit PROPERTIES EXCLUDE_FROM_ALL 1)
|
||||
if(MSVC)
|
||||
target_compile_definitions(libluajit PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||
target_compile_definitions(minilua PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||
target_compile_definitions(buildvm PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
include_directories(deps/luajit/src ${CMAKE_BINARY_DIR}/luajit)
|
||||
set(LOVR_LUA libluajit)
|
||||
endif()
|
||||
|
@ -616,18 +623,28 @@ foreach(path ${LOVR_RESOURCES})
|
|||
endforeach()
|
||||
|
||||
# Add a custom target that is always out of date so libraries are always moved
|
||||
add_custom_target(move_libraries ALL)
|
||||
add_custom_target(move_files ALL)
|
||||
|
||||
# Moves something from etc to the build directory
|
||||
function(move_resource)
|
||||
set(SRC "${CMAKE_CURRENT_SOURCE_DIR}/etc/${ARGV0}")
|
||||
add_custom_command(TARGET lovr POST_BUILD
|
||||
DEPENDS ${SRC}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${SRC} $<TARGET_FILE_DIR:lovr>/${ARGV0}
|
||||
)
|
||||
endfunction()
|
||||
|
||||
# Platforms
|
||||
if(WIN32)
|
||||
target_sources(lovr PRIVATE src/core/os_win32.c)
|
||||
target_sources(lovr PRIVATE etc/lovr.rc)
|
||||
if (MSVC)
|
||||
set_target_properties(lovr PROPERTIES COMPILE_FLAGS "/wd4244 /MP")
|
||||
set_target_properties(lovr PROPERTIES COMPILE_FLAGS /wd4244)
|
||||
# Excuse anonymous union for type punning
|
||||
set_source_files_properties(src/util.c src/modules/graphics/graphics.c PROPERTIES COMPILE_FLAGS /wd4116)
|
||||
# Excuse unsigned negation for flag-magic bit math
|
||||
set_source_files_properties(src/modules/audio/audio.c PROPERTIES COMPILE_FLAGS /wd4146)
|
||||
set_source_files_properties(src/lib/minimp3/minimp3.c PROPERTIES COMPILE_FLAGS /wd4267)
|
||||
else()
|
||||
set_target_properties(lovr PROPERTIES COMPILE_FLAGS "-MP")
|
||||
endif()
|
||||
|
@ -644,7 +661,7 @@ if(WIN32)
|
|||
|
||||
function(move_dll)
|
||||
if(TARGET ${ARGV0})
|
||||
add_custom_command(TARGET move_libraries POST_BUILD
|
||||
add_custom_command(TARGET move_files POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
$<TARGET_FILE:${ARGV0}>
|
||||
$<TARGET_FILE_DIR:lovr>/$<TARGET_FILE_NAME:${ARGV0}>
|
||||
|
@ -662,6 +679,7 @@ if(WIN32)
|
|||
foreach(target ${ALL_PLUGIN_TARGETS})
|
||||
move_dll(${target})
|
||||
endforeach()
|
||||
move_resource("lovrc.bat")
|
||||
elseif(APPLE)
|
||||
find_library(AVFOUNDATION AVFoundation)
|
||||
target_link_libraries(lovr objc ${AVFOUNDATION})
|
||||
|
@ -688,13 +706,13 @@ elseif(APPLE)
|
|||
if(TARGET ${ARGV0})
|
||||
get_target_property(TARGET_TYPE ${ARGV0} TYPE)
|
||||
if(${TARGET_TYPE} STREQUAL "MODULE_LIBRARY")
|
||||
add_custom_command(TARGET move_libraries POST_BUILD
|
||||
add_custom_command(TARGET move_files POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
$<TARGET_FILE:${ARGV0}>
|
||||
${EXE_DIR}/$<TARGET_FILE_NAME:${ARGV0}>
|
||||
)
|
||||
else()
|
||||
add_custom_command(TARGET move_libraries POST_BUILD
|
||||
add_custom_command(TARGET move_files POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
$<TARGET_SONAME_FILE:${ARGV0}>
|
||||
${EXE_DIR}/$<TARGET_SONAME_FILE_NAME:${ARGV0}>
|
||||
|
@ -800,13 +818,13 @@ elseif(ANDROID)
|
|||
|
||||
# Copy plugin libraries to lib folder before packaging APK
|
||||
foreach(target ${ALL_PLUGIN_TARGETS})
|
||||
add_custom_command(TARGET move_libraries POST_BUILD
|
||||
add_custom_command(TARGET move_files POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
$<TARGET_FILE:${target}>
|
||||
raw/lib/${ANDROID_ABI}/$<TARGET_FILE_NAME:${target}>
|
||||
)
|
||||
endforeach()
|
||||
add_dependencies(buildAPK move_libraries)
|
||||
add_dependencies(buildAPK move_files)
|
||||
endif()
|
||||
elseif(UNIX)
|
||||
target_sources(lovr PRIVATE src/core/os_linux.c)
|
||||
|
@ -819,13 +837,13 @@ elseif(UNIX)
|
|||
if(TARGET ${ARGV0})
|
||||
get_target_property(TARGET_TYPE ${ARGV0} TYPE)
|
||||
if(${TARGET_TYPE} STREQUAL "MODULE_LIBRARY")
|
||||
add_custom_command(TARGET move_libraries POST_BUILD
|
||||
add_custom_command(TARGET move_files POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
$<TARGET_FILE:${ARGV0}>
|
||||
${CMAKE_BINARY_DIR}/bin/$<TARGET_FILE_NAME:${ARGV0}>
|
||||
)
|
||||
elseif(${TARGET_TYPE} STREQUAL "SHARED_LIBRARY")
|
||||
add_custom_command(TARGET move_libraries POST_BUILD
|
||||
add_custom_command(TARGET move_files POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
$<TARGET_SONAME_FILE:${ARGV0}>
|
||||
${CMAKE_BINARY_DIR}/bin/$<TARGET_SONAME_FILE_NAME:${ARGV0}>
|
||||
|
@ -833,14 +851,6 @@ elseif(UNIX)
|
|||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
function(move_app_image_file)
|
||||
set(SRC "${CMAKE_CURRENT_SOURCE_DIR}/etc/${ARGV0}")
|
||||
set(DST "${CMAKE_BINARY_DIR}/bin/${ARGV0}")
|
||||
add_custom_command(TARGET lovr POST_BUILD
|
||||
DEPENDS ${SRC}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${SRC} ${DST}
|
||||
)
|
||||
endfunction()
|
||||
move_lib(${LOVR_GLFW})
|
||||
move_lib(${LOVR_LUA})
|
||||
move_lib(${LOVR_ODE})
|
||||
|
@ -851,8 +861,8 @@ elseif(UNIX)
|
|||
move_lib(${target})
|
||||
endforeach()
|
||||
if(LOVR_BUILD_BUNDLE)
|
||||
move_app_image_file("lovr.desktop")
|
||||
move_app_image_file("AppRun")
|
||||
move_app_image_file("logo.svg")
|
||||
move_resource("lovr.desktop")
|
||||
move_resource("AppRun")
|
||||
move_resource("logo.svg")
|
||||
endif()
|
||||
endif()
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2022 Bjorn Swenson and other LÖVR contributors
|
||||
Copyright (c) 2023 Bjorn Swenson and other LÖVR contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -8,7 +8,8 @@ You can use LÖVR to easily create VR experiences without much setup or programm
|
|||
|
||||
[![Build](https://github.com/bjornbytes/lovr/actions/workflows/build.yml/badge.svg?event=push)](https://github.com/bjornbytes/lovr/actions/workflows/build.yml)
|
||||
[![Version](https://img.shields.io/github/release/bjornbytes/lovr.svg?label=version)](https://github.com/bjornbytes/lovr/releases)
|
||||
[![Matrix](https://img.shields.io/badge/chat-matrix-7e4e76.svg)](https://lovr.org/matrix)
|
||||
[![Matrix](https://img.shields.io/badge/chat-matrix-0ba378.svg)](https://lovr.org/matrix)
|
||||
[![Discord](https://img.shields.io/badge/chat-discord-404eed.svg)](https://lovr.org/discord)
|
||||
|
||||
[**Homepage**](https://lovr.org) | [**Documentation**](https://lovr.org/docs) | [**FAQ**](https://lovr.org/docs/FAQ)
|
||||
|
||||
|
|
|
@ -103,7 +103,8 @@ cflags = {
|
|||
'-Ietc',
|
||||
'-Isrc',
|
||||
'-Isrc/modules',
|
||||
'-Isrc/lib/stdatomic'
|
||||
'-Isrc/lib/stdatomic',
|
||||
'-Ideps/vulkan-headers/include'
|
||||
}
|
||||
|
||||
bin = target == 'android' and 'bin/apk/lib/arm64-v8a' or 'bin'
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 3f77ce6ac70e8e558e18f638a77b5bcbbf31ca06
|
||||
Subproject commit 6f7eda06adc23bc14ca2e14190d69ae1d00f1740
|
|
@ -227,7 +227,8 @@ function lovr.threaderror(thread, err)
|
|||
end
|
||||
|
||||
function lovr.log(message, level, tag)
|
||||
print(message:gsub('\n$', ''))
|
||||
message = message:gsub('\n$', '')
|
||||
print(message)
|
||||
end
|
||||
|
||||
return function()
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
lovr --console %*
|
BIN
etc/monkey.glb
BIN
etc/monkey.glb
Binary file not shown.
3104
etc/monkey.h
3104
etc/monkey.h
File diff suppressed because it is too large
Load Diff
|
@ -42,7 +42,7 @@ io.write('};\n\n')
|
|||
|
||||
io.write('uint16_t monkey_indices[] = {\n ')
|
||||
for i = 1, model:getMeshIndexCount(1) do
|
||||
local index = model:getMeshIndex(1, i)
|
||||
local index = model:getMeshIndex(1, i) - 1
|
||||
io.write((' %d,'):format(index))
|
||||
if i % 10 == 0 then
|
||||
io.write('\n ')
|
||||
|
|
|
@ -26,10 +26,11 @@ static int l_lovrBlobGetString(lua_State* L) {
|
|||
uint32_t offset = luax_optu32(L, 2, 0);
|
||||
lovrCheck(offset < blob->size, "Blob byte offset must be less than the size of the Blob");
|
||||
|
||||
uint32_t length = luax_optu32(L, 3, blob->size - offset);
|
||||
lovrCheck(length <= blob->size - offset, "Blob:getString range overflows the length of the Blob");
|
||||
lua_Integer length = luaL_optinteger(L, 3, blob->size - offset);
|
||||
lovrCheck(length >= 0, "Length can not be negative");
|
||||
lovrCheck((size_t) length <= blob->size - offset, "Blob:getString range overflows the length of the Blob");
|
||||
|
||||
lua_pushlstring(L, (char*) blob->data + offset, length);
|
||||
lua_pushlstring(L, (char*) blob->data + offset, (size_t) length);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -386,7 +386,7 @@ static int l_lovrModelDataGetMeshVertex(lua_State* L) {
|
|||
ModelAttribute* attribute = mesh->attributes[i];
|
||||
if (!attribute) continue;
|
||||
|
||||
uint32_t stride = model->buffers[attribute->buffer].stride;
|
||||
size_t stride = model->buffers[attribute->buffer].stride;
|
||||
|
||||
if (!stride) {
|
||||
switch (attribute->type) {
|
||||
|
@ -697,9 +697,9 @@ static int l_lovrModelDataGetAnimationKeyframe(lua_State* L) {
|
|||
uint32_t keyframe = luax_checku32(L, 4) - 1;
|
||||
lovrCheck(keyframe < channel->keyframeCount, "Invalid keyframe index '%d'", keyframe + 1);
|
||||
lua_pushnumber(L, channel->times[keyframe]);
|
||||
size_t counts[] = { [PROP_TRANSLATION] = 3, [PROP_ROTATION] = 4, [PROP_SCALE] = 3 };
|
||||
size_t count = counts[channel->property];
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
int counts[] = { [PROP_TRANSLATION] = 3, [PROP_ROTATION] = 4, [PROP_SCALE] = 3 };
|
||||
int count = counts[channel->property];
|
||||
for (int i = 0; i < count; i++) {
|
||||
lua_pushnumber(L, channel->data[keyframe * count + i]);
|
||||
}
|
||||
return count + 1;
|
||||
|
|
|
@ -45,7 +45,7 @@ void luax_checkvariant(lua_State* L, int index, Variant* variant) {
|
|||
const char* string = lua_tolstring(L, index, &length);
|
||||
if (length <= sizeof(variant->value.ministring.data)) {
|
||||
variant->type = TYPE_MINISTRING;
|
||||
variant->value.ministring.length = length;
|
||||
variant->value.ministring.length = (uint8_t) length;
|
||||
memcpy(variant->value.ministring.data, string, length);
|
||||
} else {
|
||||
variant->type = TYPE_STRING;
|
||||
|
|
|
@ -150,6 +150,19 @@ static int l_lovrWorldGetColliders(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrWorldGetTags(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
lua_newtable(L);
|
||||
for (uint32_t i = 0; i < MAX_TAGS; i++) {
|
||||
const char* tag = lovrWorldGetTagName(world, i);
|
||||
if (tag == NULL)
|
||||
break;
|
||||
lua_pushstring(L, tag);
|
||||
lua_rawseti(L, -2, i + 1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrWorldDestroy(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
lovrWorldDestroyData(world);
|
||||
|
@ -371,6 +384,7 @@ const luaL_Reg lovrWorld[] = {
|
|||
{ "newMeshCollider", l_lovrWorldNewMeshCollider },
|
||||
{ "newTerrainCollider", l_lovrWorldNewTerrainCollider },
|
||||
{ "getColliders", l_lovrWorldGetColliders },
|
||||
{ "getTags", l_lovrWorldGetTags },
|
||||
{ "destroy", l_lovrWorldDestroy },
|
||||
{ "update", l_lovrWorldUpdate },
|
||||
{ "computeOverlaps", l_lovrWorldComputeOverlaps },
|
||||
|
|
|
@ -188,6 +188,11 @@ static struct {
|
|||
uint32_t tick[2];
|
||||
gpu_tick ticks[4];
|
||||
gpu_morgue morgue;
|
||||
struct {
|
||||
bool validation;
|
||||
bool portability;
|
||||
bool debug;
|
||||
} supports;
|
||||
} state;
|
||||
|
||||
// Helpers
|
||||
|
@ -1842,79 +1847,72 @@ bool gpu_init(gpu_config* config) {
|
|||
#endif
|
||||
GPU_FOREACH_ANONYMOUS(GPU_LOAD_ANONYMOUS);
|
||||
|
||||
{ // Instance
|
||||
struct {
|
||||
bool validation;
|
||||
bool portability;
|
||||
bool debug;
|
||||
} supports = { 0 };
|
||||
|
||||
{
|
||||
// Layers
|
||||
|
||||
struct { const char* name; bool shouldEnable; bool* isEnabled; } layers[] = {
|
||||
{ "VK_LAYER_KHRONOS_validation", config->debug, &supports.validation }
|
||||
VkLayerProperties layerInfo[32];
|
||||
uint32_t layerCount = COUNTOF(layerInfo);
|
||||
VK(vkEnumerateInstanceLayerProperties(&layerCount, layerInfo), "Failed to enumerate instance layers") return gpu_destroy(), false;
|
||||
|
||||
struct { const char* name; bool shouldEnable; bool* flag; } layers[] = {
|
||||
{ "VK_LAYER_KHRONOS_validation", config->debug, &state.supports.validation }
|
||||
};
|
||||
|
||||
const char* enabledLayers[1];
|
||||
uint32_t enabledLayerCount = 0;
|
||||
|
||||
VkLayerProperties layerInfo[32];
|
||||
uint32_t count = COUNTOF(layerInfo);
|
||||
VK(vkEnumerateInstanceLayerProperties(&count, layerInfo), "Failed to enumerate instance layers") return gpu_destroy(), false;
|
||||
|
||||
const char* enabledLayers[COUNTOF(layers)];
|
||||
for (uint32_t i = 0; i < COUNTOF(layers); i++) {
|
||||
if (!layers[i].shouldEnable) continue;
|
||||
if (hasLayer(layerInfo, count, layers[i].name)) {
|
||||
if (hasLayer(layerInfo, layerCount, layers[i].name)) {
|
||||
CHECK(enabledLayerCount < COUNTOF(enabledLayers), "Too many layers") return gpu_destroy(), false;
|
||||
if (layers[i].isEnabled) *layers[i].isEnabled = true;
|
||||
if (layers[i].flag) *layers[i].flag = true;
|
||||
enabledLayers[enabledLayerCount++] = layers[i].name;
|
||||
} else if (!layers[i].flag) {
|
||||
vcheck(VK_ERROR_LAYER_NOT_PRESENT, layers[i].name);
|
||||
return gpu_destroy(), false;
|
||||
}
|
||||
}
|
||||
|
||||
// Extensions
|
||||
|
||||
struct { const char* name; bool shouldEnable; bool* isEnabled; } extensions[] = {
|
||||
{ "VK_KHR_portability_enumeration", true, &supports.portability },
|
||||
{ "VK_EXT_debug_utils", config->debug, &supports.debug }
|
||||
VkExtensionProperties extensionInfo[64];
|
||||
uint32_t extensionCount = COUNTOF(extensionInfo);
|
||||
VK(vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, extensionInfo), "Failed to enumerate instance extensions") return gpu_destroy(), false;
|
||||
|
||||
struct { const char* name; bool shouldEnable; bool* flag; } extensions[] = {
|
||||
{ "VK_KHR_portability_enumeration", true, &state.supports.portability },
|
||||
{ "VK_EXT_debug_utils", config->debug, &state.supports.debug },
|
||||
{ 0 }, // extra extensions for GLFW
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
const char* enabledExtensions[32];
|
||||
uint32_t enabledExtensionCount = 0;
|
||||
|
||||
if (state.config.vk.getInstanceExtensions) {
|
||||
const char** instanceExtensions = state.config.vk.getInstanceExtensions(&enabledExtensionCount);
|
||||
CHECK(enabledExtensionCount < COUNTOF(enabledExtensions), "Too many instance extensions") return gpu_destroy(), false;
|
||||
for (uint32_t i = 0; i < enabledExtensionCount; i++) {
|
||||
enabledExtensions[i] = instanceExtensions[i];
|
||||
}
|
||||
}
|
||||
|
||||
VkExtensionProperties extensionInfo[256];
|
||||
count = COUNTOF(extensionInfo);
|
||||
VK(vkEnumerateInstanceExtensionProperties(NULL, &count, extensionInfo), "Failed to enumerate instance extensions") return gpu_destroy(), false;
|
||||
|
||||
const char* enabledExtensions[COUNTOF(extensions)];
|
||||
for (uint32_t i = 0; i < COUNTOF(extensions); i++) {
|
||||
if (!extensions[i].shouldEnable) continue;
|
||||
if (hasExtension(extensionInfo, count, extensions[i].name)) {
|
||||
if (hasExtension(extensionInfo, extensionCount, extensions[i].name)) {
|
||||
CHECK(enabledExtensionCount < COUNTOF(enabledExtensions), "Too many instance extensions") return gpu_destroy(), false;
|
||||
if (extensions[i].isEnabled) *extensions[i].isEnabled = true;
|
||||
if (extensions[i].flag) *extensions[i].flag = true;
|
||||
enabledExtensions[enabledExtensionCount++] = extensions[i].name;
|
||||
} else if (!extensions[i].flag) {
|
||||
vcheck(VK_ERROR_EXTENSION_NOT_PRESENT, extensions[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
if (state.config.debug && !supports.validation && state.config.callback) {
|
||||
state.config.callback(state.config.userdata, "Warning: GPU debug mode is enabled, but validation layer is not supported", false);
|
||||
// Extra extensions (from GLFW)
|
||||
if (state.config.vk.getInstanceExtensions) {
|
||||
uint32_t extraExtensionCount = 0;
|
||||
const char** extraExtensions = state.config.vk.getInstanceExtensions(&extraExtensionCount);
|
||||
CHECK(enabledExtensionCount + extraExtensionCount <= COUNTOF(enabledExtensions), "Too many instance extensions") return gpu_destroy(), false;
|
||||
for (uint32_t i = 0; i < extraExtensionCount; i++) {
|
||||
enabledExtensions[enabledExtensionCount++] = extraExtensions[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (state.config.debug && !supports.debug) {
|
||||
state.config.debug = false;
|
||||
}
|
||||
// Instance
|
||||
|
||||
VkInstanceCreateInfo instanceInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||
#ifdef VK_KHR_portability_enumeration
|
||||
.flags = supports.portability ? VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR : 0,
|
||||
#endif
|
||||
.flags = state.supports.portability ? VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR : 0,
|
||||
.pApplicationInfo = &(VkApplicationInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
||||
.pEngineName = config->engineName,
|
||||
|
@ -1935,15 +1933,23 @@ bool gpu_init(gpu_config* config) {
|
|||
|
||||
GPU_FOREACH_INSTANCE(GPU_LOAD_INSTANCE);
|
||||
|
||||
if (state.config.debug) {
|
||||
VkDebugUtilsMessengerCreateInfoEXT messengerInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
|
||||
.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
|
||||
.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
|
||||
.pfnUserCallback = relay
|
||||
};
|
||||
if (state.config.debug && state.config.callback) {
|
||||
if (state.supports.debug) {
|
||||
VkDebugUtilsMessengerCreateInfoEXT messengerInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
|
||||
.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
|
||||
.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
|
||||
.pfnUserCallback = relay
|
||||
};
|
||||
|
||||
VK(vkCreateDebugUtilsMessengerEXT(state.instance, &messengerInfo, NULL, &state.messenger), "Debug hook setup failed") return gpu_destroy(), false;
|
||||
VK(vkCreateDebugUtilsMessengerEXT(state.instance, &messengerInfo, NULL, &state.messenger), "Debug hook setup failed") return gpu_destroy(), false;
|
||||
|
||||
if (!state.supports.validation) {
|
||||
state.config.callback(state.config.userdata, "Warning: GPU debugging is enabled, but validation layer is not installed", false);
|
||||
}
|
||||
} else {
|
||||
state.config.callback(state.config.userdata, "Warning: GPU debugging is enabled, but debug extension is not supported", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2096,33 +2102,28 @@ bool gpu_init(gpu_config* config) {
|
|||
}
|
||||
CHECK(state.queueFamilyIndex != ~0u, "Queue selection failed") return gpu_destroy(), false;
|
||||
|
||||
struct {
|
||||
bool swapchain;
|
||||
} supports = { 0 };
|
||||
|
||||
struct { const char* name; bool shouldEnable; bool* isEnabled; } extensions[] = {
|
||||
{ "VK_KHR_swapchain", state.surface, &supports.swapchain },
|
||||
{ "VK_KHR_portability_subset", true, NULL }
|
||||
struct { const char* name; bool shouldEnable; bool* flag; } extensions[] = {
|
||||
{ "VK_KHR_swapchain", state.surface, NULL },
|
||||
{ "VK_KHR_portability_subset", true, &state.supports.portability }
|
||||
};
|
||||
|
||||
const char* enabledExtensions[4];
|
||||
uint32_t enabledExtensionCount = 0;
|
||||
|
||||
VkExtensionProperties extensionInfo[256];
|
||||
uint32_t count = COUNTOF(extensionInfo);
|
||||
VK(vkEnumerateDeviceExtensionProperties(state.adapter, NULL, &count, extensionInfo), "Failed to enumerate device extensions") return gpu_destroy(), false;
|
||||
uint32_t extensionCount = COUNTOF(extensionInfo);
|
||||
VK(vkEnumerateDeviceExtensionProperties(state.adapter, NULL, &extensionCount, extensionInfo), "Failed to enumerate device extensions") return gpu_destroy(), false;
|
||||
|
||||
uint32_t enabledExtensionCount = 0;
|
||||
const char* enabledExtensions[COUNTOF(extensions)];
|
||||
for (uint32_t i = 0; i < COUNTOF(extensions); i++) {
|
||||
if (!extensions[i].shouldEnable) continue;
|
||||
if (hasExtension(extensionInfo, count, extensions[i].name)) {
|
||||
if (hasExtension(extensionInfo, extensionCount, extensions[i].name)) {
|
||||
CHECK(enabledExtensionCount < COUNTOF(enabledExtensions), "Too many device extensions") return gpu_destroy(), false;
|
||||
if (extensions[i].isEnabled) *extensions[i].isEnabled = true;
|
||||
if (extensions[i].flag) *extensions[i].flag = true;
|
||||
enabledExtensions[enabledExtensionCount++] = extensions[i].name;
|
||||
} else if (!extensions[i].flag) {
|
||||
vcheck(VK_ERROR_EXTENSION_NOT_PRESENT, extensions[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(supports.swapchain || !state.surface, "Swapchain extension not supported") return gpu_destroy(), false;
|
||||
|
||||
VkDeviceCreateInfo deviceInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
||||
.pNext = config->features ? &enabledFeatures : NULL,
|
||||
|
@ -2142,6 +2143,7 @@ bool gpu_init(gpu_config* config) {
|
|||
} else {
|
||||
VK(vkCreateDevice(state.adapter, &deviceInfo, NULL, &state.device), "Device creation failed") return gpu_destroy(), false;
|
||||
}
|
||||
|
||||
vkGetDeviceQueue(state.device, state.queueFamilyIndex, 0, &state.queue);
|
||||
GPU_FOREACH_DEVICE(GPU_LOAD_DEVICE);
|
||||
}
|
||||
|
@ -3046,14 +3048,12 @@ static VkAccessFlags convertCache(gpu_cache cache) {
|
|||
}
|
||||
|
||||
static VkBool32 relay(VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageTypeFlagsEXT flags, const VkDebugUtilsMessengerCallbackDataEXT* data, void* userdata) {
|
||||
if (state.config.callback) {
|
||||
state.config.callback(state.config.userdata, data->pMessage, false);
|
||||
}
|
||||
state.config.callback(state.config.userdata, data->pMessage, false);
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
static void nickname(void* handle, VkObjectType type, const char* name) {
|
||||
if (name && state.config.debug) {
|
||||
if (name && state.supports.debug) {
|
||||
union { uint64_t u64; void* p; } pointer = { .p = handle };
|
||||
|
||||
VkDebugUtilsObjectNameInfoEXT info = {
|
||||
|
|
|
@ -138,7 +138,7 @@ static bool loadOgg(Sound* sound, Blob* blob, bool decode) {
|
|||
void* data = calloc(1, size);
|
||||
lovrAssert(data, "Out of memory");
|
||||
sound->blob = lovrBlobCreate(data, size, "Sound");
|
||||
if (stb_vorbis_get_samples_float_interleaved(sound->decoder, channels, data, size / sizeof(float)) < (int) sound->frames) {
|
||||
if (stb_vorbis_get_samples_float_interleaved(sound->decoder, channels, data, (int) size / sizeof(float)) < (int) sound->frames) {
|
||||
lovrThrow("Could not decode vorbis from '%s'", blob->name);
|
||||
}
|
||||
stb_vorbis_close(sound->decoder);
|
||||
|
|
|
@ -1519,7 +1519,6 @@ ShaderSource lovrGraphicsCompileShader(ShaderStage stage, ShaderSource* source)
|
|||
|
||||
int options = 0;
|
||||
options |= GLSLANG_SHADER_AUTO_MAP_BINDINGS;
|
||||
options |= GLSLANG_SHADER_AUTO_MAP_LOCATIONS;
|
||||
|
||||
glslang_shader_set_options(shader, options);
|
||||
|
||||
|
@ -1714,6 +1713,8 @@ Shader* lovrShaderCreate(const ShaderInfo* info) {
|
|||
lovrAssert(shader->constants && shader->resources && shader->attributes, "Out of memory");
|
||||
lovrAssert(shader->flags && shader->flagLookup, "Out of memory");
|
||||
|
||||
lovrCheck(shader->constantSize <= state.limits.pushConstantSize, "Shader push constants block is too big");
|
||||
|
||||
// Push constants
|
||||
for (uint32_t i = 0; i < spv[constantStage].pushConstantCount; i++) {
|
||||
static const FieldType constantTypes[] = {
|
||||
|
@ -4935,6 +4936,10 @@ void lovrPassTorus(Pass* pass, float* transform, uint32_t segmentsT, uint32_t se
|
|||
.index.count = indexCount
|
||||
});
|
||||
|
||||
if (!vertices) {
|
||||
return;
|
||||
}
|
||||
|
||||
// T and P stand for toroidal and poloidal, or theta and phi
|
||||
float dt = (2.f * (float) M_PI) / segmentsT;
|
||||
float dp = (2.f * (float) M_PI) / segmentsP;
|
||||
|
|
|
@ -17,19 +17,19 @@ static void evaluate(float* restrict P, size_t n, float t, vec3 p) {
|
|||
p[2] = P[2] + (P[6] - P[2]) * t;
|
||||
p[3] = P[3] + (P[7] - P[3]) * t;
|
||||
} else if (n == 3) {
|
||||
float t1 = (1 - t);
|
||||
float t1 = (1.f - t);
|
||||
float a = t1 * t1;
|
||||
float b = 2 * t1 * t;
|
||||
float b = 2.f * t1 * t;
|
||||
float c = t * t;
|
||||
p[0] = a * P[0] + b * P[4] + c * P[8];
|
||||
p[1] = a * P[1] + b * P[5] + c * P[9];
|
||||
p[2] = a * P[2] + b * P[6] + c * P[10];
|
||||
p[3] = a * P[3] + b * P[7] + c * P[11];
|
||||
} else if (n == 4) {
|
||||
float t1 = (1 - t);
|
||||
float t1 = (1.f - t);
|
||||
float a = t1 * t1 * t1;
|
||||
float b = 3 * t1 * t1 * t;
|
||||
float c = 3 * t1 * t * t;
|
||||
float b = 3.f * t1 * t1 * t;
|
||||
float c = 3.f * t1 * t * t;
|
||||
float d = t * t * t;
|
||||
p[0] = a * P[0] + b * P[4] + c * P[8] + d * P[12];
|
||||
p[1] = a * P[1] + b * P[5] + c * P[9] + d * P[13];
|
||||
|
@ -39,7 +39,7 @@ static void evaluate(float* restrict P, size_t n, float t, vec3 p) {
|
|||
float b = 1.f;
|
||||
p[0] = p[1] = p[2] = p[3] = 0.f;
|
||||
for (size_t i = 0; i < n; i++, b *= (float) (n - i) / i) {
|
||||
float c1 = powf(1 - t, n - (i + 1));
|
||||
float c1 = powf(1.f - t, n - (i + 1));
|
||||
float c2 = powf(t, i);
|
||||
p[0] += b * c1 * c2 * P[i * 4 + 0];
|
||||
p[1] += b * c1 * c2 * P[i * 4 + 1];
|
||||
|
|
Loading…
Reference in New Issue