mirror of
https://github.com/armory3d/armorpaint.git
synced 2026-10-02 02:54:34 +08:00
base: wasm fixes
This commit is contained in:
@@ -180,17 +180,22 @@ function id_to_filter_mode(id) {
|
||||
return "linear";
|
||||
}
|
||||
|
||||
async function init() {
|
||||
let wasm_bytes = null;
|
||||
await fetch("./start.wasm").then(res => res.arrayBuffer()).then(buffer => wasm_bytes = new Uint8Array(buffer));
|
||||
|
||||
memory = new WebAssembly.Memory({initial : 10240, maximum : 10240, shared : true}); // * 65536 = 671088640 (amake --initial-memory)
|
||||
function update_heap_views() {
|
||||
heapu8 = new Uint8Array(memory.buffer);
|
||||
heapu16 = new Uint16Array(memory.buffer);
|
||||
heapu32 = new Uint32Array(memory.buffer);
|
||||
heapi32 = new Int32Array(memory.buffer);
|
||||
heapf32 = new Float32Array(memory.buffer);
|
||||
heapf64 = new Float64Array(memory.buffer);
|
||||
}
|
||||
|
||||
async function init() {
|
||||
let wasm_bytes = null;
|
||||
await fetch("./start.wasm").then(res => res.arrayBuffer()).then(buffer => wasm_bytes = new Uint8Array(buffer));
|
||||
|
||||
// * 65536 = amake --initial-memory=268435456, --max-memory=4294967296, malloc grows it
|
||||
memory = new WebAssembly.Memory({initial : 4096, maximum : 65536, shared : true});
|
||||
update_heap_views();
|
||||
|
||||
if (!navigator.gpu) {
|
||||
throw new Error('WebGPU not supported');
|
||||
@@ -716,6 +721,9 @@ async function init() {
|
||||
surface.configure(config);
|
||||
},
|
||||
|
||||
js_memory_grow : function() {
|
||||
update_heap_views();
|
||||
},
|
||||
js_printf : function(format) {
|
||||
console.log(read_string(format));
|
||||
},
|
||||
@@ -775,8 +783,8 @@ async function init() {
|
||||
js_time : function() {
|
||||
return window.performance.now();
|
||||
},
|
||||
js_pow : function(x) {
|
||||
return Math.pow(x);
|
||||
js_pow : function(base, exponent) {
|
||||
return Math.pow(base, exponent);
|
||||
},
|
||||
js_sin : function(x) {
|
||||
return Math.sin(x);
|
||||
@@ -787,8 +795,8 @@ async function init() {
|
||||
js_tan : function(x) {
|
||||
return Math.tan(x);
|
||||
},
|
||||
js_log : function(base, exponent) {
|
||||
return Math.log(base, exponent);
|
||||
js_log : function(x) {
|
||||
return Math.log(x);
|
||||
},
|
||||
js_exp : function(x) {
|
||||
return Math.exp(x);
|
||||
|
||||
+15
-10
@@ -355,6 +355,11 @@ iron_a1_sound_t *iron_a1_sound_create_from_bytes(uint8_t *filedata, int filedata
|
||||
if (strncmp(format, ".ogg", 4) == 0) {
|
||||
int channels, sample_rate;
|
||||
int samples = stb_vorbis_decode_memory(filedata, (int)filedata_size, &channels, &sample_rate, (short **)&data);
|
||||
if (samples <= 0) {
|
||||
free(data);
|
||||
sound->in_use = false;
|
||||
return NULL;
|
||||
}
|
||||
sound->channel_count = (uint8_t)channels;
|
||||
sound->samples_per_second = (uint32_t)sample_rate;
|
||||
sound->size = samples * 2 * sound->channel_count;
|
||||
@@ -571,48 +576,48 @@ float *iron_a1_sound_stream_next_frame(iron_a1_sound_stream_t *stream) {
|
||||
return stream->samples;
|
||||
}
|
||||
|
||||
static iron_mutex_t mutex;
|
||||
static iron_mutex_t a2_mutex;
|
||||
|
||||
static void (*a2_callback)(iron_a2_buffer_t *buffer, uint32_t samples, void *userdata) = NULL;
|
||||
static void *a2_userdata = NULL;
|
||||
|
||||
void iron_a2_set_callback(void (*iron_a2_audio_callback)(iron_a2_buffer_t *buffer, uint32_t samples, void *userdata), void *userdata) {
|
||||
iron_mutex_lock(&mutex);
|
||||
iron_mutex_lock(&a2_mutex);
|
||||
a2_callback = iron_a2_audio_callback;
|
||||
a2_userdata = userdata;
|
||||
iron_mutex_unlock(&mutex);
|
||||
iron_mutex_unlock(&a2_mutex);
|
||||
}
|
||||
|
||||
static void (*a2_sample_rate_callback)(void *userdata) = NULL;
|
||||
static void *a2_sample_rate_userdata = NULL;
|
||||
|
||||
void iron_a2_set_sample_rate_callback(void (*iron_a2_sample_rate_callback)(void *userdata), void *userdata) {
|
||||
iron_mutex_lock(&mutex);
|
||||
iron_mutex_lock(&a2_mutex);
|
||||
a2_sample_rate_callback = iron_a2_sample_rate_callback;
|
||||
a2_sample_rate_userdata = userdata;
|
||||
iron_mutex_unlock(&mutex);
|
||||
iron_mutex_unlock(&a2_mutex);
|
||||
}
|
||||
|
||||
void iron_a2_internal_init(void) {
|
||||
iron_mutex_init(&mutex);
|
||||
iron_mutex_init(&a2_mutex);
|
||||
}
|
||||
|
||||
bool iron_a2_internal_callback(iron_a2_buffer_t *buffer, int samples) {
|
||||
iron_mutex_lock(&mutex);
|
||||
iron_mutex_lock(&a2_mutex);
|
||||
bool has_callback = a2_callback != NULL;
|
||||
if (has_callback) {
|
||||
a2_callback(buffer, samples, a2_userdata);
|
||||
}
|
||||
iron_mutex_unlock(&mutex);
|
||||
iron_mutex_unlock(&a2_mutex);
|
||||
return has_callback;
|
||||
}
|
||||
|
||||
void iron_a2_internal_sample_rate_callback(void) {
|
||||
iron_mutex_lock(&mutex);
|
||||
iron_mutex_lock(&a2_mutex);
|
||||
if (a2_sample_rate_callback != NULL) {
|
||||
a2_sample_rate_callback(a2_sample_rate_userdata);
|
||||
}
|
||||
iron_mutex_unlock(&mutex);
|
||||
iron_mutex_unlock(&a2_mutex);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
#include "math.h"
|
||||
|
||||
#ifdef IRON_WASM
|
||||
__attribute__((import_module("imports"), import_name("js_pow"))) float js_pow(float base, float exponent);
|
||||
__attribute__((import_module("imports"), import_name("js_sin"))) float js_sin(float x);
|
||||
__attribute__((import_module("imports"), import_name("js_cos"))) float js_cos(float x);
|
||||
__attribute__((import_module("imports"), import_name("js_tan"))) float js_tan(float x);
|
||||
__attribute__((import_module("imports"), import_name("js_log"))) float js_log(float x);
|
||||
__attribute__((import_module("imports"), import_name("js_exp"))) float js_exp(float x);
|
||||
__attribute__((import_module("imports"), import_name("js_sqrt"))) float js_sqrt(float x);
|
||||
__attribute__((import_module("imports"), import_name("js_acos"))) float js_acos(float x);
|
||||
__attribute__((import_module("imports"), import_name("js_asin"))) float js_asin(float x);
|
||||
__attribute__((import_module("imports"), import_name("js_atan"))) float js_atan(float x);
|
||||
__attribute__((import_module("imports"), import_name("js_atan2"))) float js_atan2(float x, float y);
|
||||
__attribute__((import_module("imports"), import_name("js_pow"))) double js_pow(double base, double exponent);
|
||||
__attribute__((import_module("imports"), import_name("js_sin"))) double js_sin(double x);
|
||||
__attribute__((import_module("imports"), import_name("js_cos"))) double js_cos(double x);
|
||||
__attribute__((import_module("imports"), import_name("js_tan"))) double js_tan(double x);
|
||||
__attribute__((import_module("imports"), import_name("js_log"))) double js_log(double x);
|
||||
__attribute__((import_module("imports"), import_name("js_exp"))) double js_exp(double x);
|
||||
__attribute__((import_module("imports"), import_name("js_sqrt"))) double js_sqrt(double x);
|
||||
__attribute__((import_module("imports"), import_name("js_acos"))) double js_acos(double x);
|
||||
__attribute__((import_module("imports"), import_name("js_asin"))) double js_asin(double x);
|
||||
__attribute__((import_module("imports"), import_name("js_atan"))) double js_atan(double x);
|
||||
__attribute__((import_module("imports"), import_name("js_atan2"))) double js_atan2(double x, double y);
|
||||
#endif
|
||||
|
||||
double fabs(double n) {
|
||||
@@ -38,8 +38,25 @@ float fminf(float x, float y) {
|
||||
return x < y ? x : y;
|
||||
}
|
||||
|
||||
static double exp2_int(int exp) {
|
||||
union {
|
||||
double d;
|
||||
unsigned long long u;
|
||||
} v;
|
||||
v.u = (unsigned long long)(exp + 1023) << 52;
|
||||
return v.d;
|
||||
}
|
||||
|
||||
double ldexp(double x, int exp) {
|
||||
return x * pow(2.0, exp);
|
||||
while (exp > 1023) {
|
||||
x *= exp2_int(1023);
|
||||
exp -= 1023;
|
||||
}
|
||||
while (exp < -1022) {
|
||||
x *= exp2_int(-1022);
|
||||
exp += 1022;
|
||||
}
|
||||
return x * exp2_int(exp);
|
||||
}
|
||||
|
||||
double pow(double base, double exponent) {
|
||||
@@ -224,7 +241,14 @@ float expf(float x) {
|
||||
}
|
||||
|
||||
double exp2(double x) {
|
||||
return pow(2.0, x);
|
||||
#ifdef IRON_WASM
|
||||
return js_pow(2.0, x);
|
||||
#endif
|
||||
double r = 1.0;
|
||||
int n = (int)x;
|
||||
for (int i = 0; i < n; i++)
|
||||
r *= 2.0;
|
||||
return r;
|
||||
}
|
||||
|
||||
float exp2f(float x) {
|
||||
@@ -236,6 +260,8 @@ double frexp(double x, int *exp) {
|
||||
*exp = 0;
|
||||
return 0.0;
|
||||
}
|
||||
double sign = x < 0.0 ? -1.0 : 1.0;
|
||||
x *= sign;
|
||||
*exp = 0;
|
||||
while (x >= 1.0) {
|
||||
x /= 2.0;
|
||||
@@ -245,7 +271,7 @@ double frexp(double x, int *exp) {
|
||||
x *= 2.0;
|
||||
(*exp)--;
|
||||
}
|
||||
return x;
|
||||
return x * sign;
|
||||
}
|
||||
|
||||
float frexpf(float x, int *exp) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "stdlib.h"
|
||||
#include "ctype.h"
|
||||
#include "stdbool.h"
|
||||
#include "stddef.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
@@ -7,9 +8,36 @@
|
||||
#define ALIGNMENT 8
|
||||
#define ALIGN(size) (((size) + (ALIGNMENT - 1)) & ~(ALIGNMENT - 1))
|
||||
|
||||
#ifdef IRON_WASM
|
||||
__attribute__((import_module("imports"), import_name("js_memory_grow"))) void js_memory_grow(void);
|
||||
extern unsigned char __heap_base;
|
||||
#define heap (&__heap_base)
|
||||
#define WASM_PAGE_SIZE 65536ULL
|
||||
#define HEAP_GROW_PAGES 1024 // 64MB steps
|
||||
|
||||
static bool heap_reserve(unsigned long long end) {
|
||||
unsigned long long size = __builtin_wasm_memory_size(0) * WASM_PAGE_SIZE - (size_t)heap;
|
||||
if (end <= size) {
|
||||
return true;
|
||||
}
|
||||
size_t pages = (size_t)((end - size + WASM_PAGE_SIZE - 1) / WASM_PAGE_SIZE);
|
||||
if (__builtin_wasm_memory_grow(0, pages < HEAP_GROW_PAGES ? HEAP_GROW_PAGES : pages) == (size_t)-1 &&
|
||||
__builtin_wasm_memory_grow(0, pages) == (size_t)-1) {
|
||||
return false;
|
||||
}
|
||||
js_memory_grow();
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
#define HEAP_SIZE 1024 * 1024 * 512
|
||||
static unsigned char heap[HEAP_SIZE] __attribute__((aligned(ALIGNMENT)));
|
||||
static size_t heap_top = ALIGNMENT;
|
||||
|
||||
static bool heap_reserve(unsigned long long end) {
|
||||
return end <= HEAP_SIZE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static size_t heap_top = ALIGNMENT;
|
||||
|
||||
typedef struct block {
|
||||
size_t size;
|
||||
@@ -21,6 +49,9 @@ static block_t *free_list = NULL;
|
||||
__attribute__((export_name("wasm_malloc")))
|
||||
#endif
|
||||
void *malloc(size_t size) {
|
||||
if (size > (size_t)-1 - ALIGNMENT) {
|
||||
return NULL;
|
||||
}
|
||||
size = ALIGN(size);
|
||||
block_t **link = &free_list;
|
||||
block_t *curr = free_list;
|
||||
@@ -41,8 +72,8 @@ void *malloc(size_t size) {
|
||||
link = &curr->next;
|
||||
curr = curr->next;
|
||||
}
|
||||
if (heap_top + sizeof(block_t) + size > HEAP_SIZE) {
|
||||
printf("malloc: out of memory");
|
||||
if (!heap_reserve((unsigned long long)heap_top + sizeof(block_t) + size)) {
|
||||
printf("malloc: out of memory (%u bytes requested)\n", (unsigned)size);
|
||||
return NULL;
|
||||
}
|
||||
block_t *ptr = (block_t *)&heap[heap_top];
|
||||
|
||||
@@ -1548,7 +1548,7 @@ void export_solution(project_t *project) {
|
||||
char *compiler = "clang --target=wasm32 -nostdlib -matomics -mbulk-memory";
|
||||
char *linker =
|
||||
"--target=wasm32 -nostdlib -matomics -mbulk-memory "
|
||||
"\"-Wl,--import-memory,--shared-memory,--allow-undefined,--no-entry,--initial-memory=671088640,--max-memory=671088640,-z,stack-size=256000\"";
|
||||
"\"-Wl,--import-memory,--shared-memory,--allow-undefined,--no-entry,--initial-memory=268435456,--max-memory=4294967296,-z,stack-size=256000\"";
|
||||
if (!goptions.debug) {
|
||||
linker = string("%s -Wl,--strip-all", linker);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user