scaling done correctly for integer rendering

This commit is contained in:
John Alanbrook 2024-10-02 11:56:33 -05:00
parent fa824aec3a
commit a540e14cae
7 changed files with 63 additions and 68 deletions

View file

@ -1,14 +1,10 @@
/* /*
TYPES OF PROFILING TYPES OF PROFILING
report - can see specific events that happened. Includes inclusive vs noninclusive times. When used on top of each other, also generates a callstack.
cpu frames - gets stack frames randomly for a few seconds
report - can see specific events that happened. Includes inclusive vs noninclusive times.
snapshot - See the amount of something every amount of time snapshot - See the amount of something every amount of time
memory - can see how much memory is allocated and from where memory - can see how much memory is allocated and from where [not implemented yet]
*/ */
var t_units = ["ns", "us", "ms", "s", "ks", "Ms"];
function calc_cpu(fn, times, diff = 0) { function calc_cpu(fn, times, diff = 0) {
var series = []; var series = [];
@ -23,9 +19,8 @@ function calc_cpu(fn, times, diff = 0) {
function empty_fn() {} function empty_fn() {}
profile.cpu = function profile_cpu(fn, times = 1, q = "unnamed") { // Measure how long a fn takes to run, ignoring the overhead of a function call
var retgather = gathering_cpu; profile.cpu = function profile_cpu(fn, times = 1, q = fn) {
profile.gather_stop();
var empty = calc_cpu(empty_fn, 100000); var empty = calc_cpu(empty_fn, 100000);
var mean = Math.mean(empty); var mean = Math.mean(empty);
var series = calc_cpu(fn, times, mean); var series = calc_cpu(fn, times, mean);
@ -36,8 +31,6 @@ profile.cpu = function profile_cpu(fn, times = 1, q = "unnamed") {
say(`profile [${q}]: ${avgt} ± ${profile.best_t(Math.ci(series))} [${totalt} for ${times} loops]`); say(`profile [${q}]: ${avgt} ± ${profile.best_t(Math.ci(series))} [${totalt} for ${times} loops]`);
say(`result of function is ${fn()}`); say(`result of function is ${fn()}`);
if (retgather) profile.start_prof_gather();
}; };
profile.ms = function (t) { profile.ms = function (t) {
@ -165,21 +158,15 @@ profile.stop_cpu_measure = function()
for (var x of e) { for (var x of e) {
var ffs = x.line.split(":"); var ffs = x.line.split(":");
x.timestr = profile.best_t(x.time);
x.timeper = x.time / x.hits; x.timeper = x.time / x.hits;
x.timeperstr = profile.best_t(x.timeper);
x.pct = x.time/gathertime * 100; x.pct = x.time/gathertime * 100;
x.alone.timestr = profile.best_t(x.alone.time);
x.alone.timeper = x.alone.time / x.alone.hits; x.alone.timeper = x.alone.time / x.alone.hits;
x.alone.timeperstr = profile.best_t(x.alone.timeper);
x.alone.pct = x.alone.time / gathertime * 100; x.alone.pct = x.alone.time / gathertime * 100;
x.fncall = get_line(ffs[0], ffs[1]); x.fncall = get_line(ffs[0], ffs[1]);
x.log = x.line + " " + x.fn + " " + x.fncall; x.log = x.line + " " + x.fn + " " + x.fncall;
x.incl = { x.incl = {
time: x.time, time: x.time,
timestr: x.timestr,
timeper: x.timeper, timeper: x.timeper,
timeperstr: x.timeperstr,
hits: x.hits, hits: x.hits,
pct: x.pct, pct: x.pct,
}; };
@ -187,23 +174,6 @@ profile.stop_cpu_measure = function()
profile.cpu_instr = e; profile.cpu_instr = e;
} }
function push_time(arr, ob, max) {
arr.push({
time: profile.now(),
ob,
});
}
profile.cpu_frames = [];
profile.last_cpu_frame = undefined;
profile.cpu_frame = function () {
profile.gather(Math.random_range(300, 600), function () {
var err = new Error();
profile.last_cpu_frame = err.stack; //.split('\n').slicconsole.stack(2);
profile.gather_stop();
});
};
var filecache = {}; var filecache = {};
function get_line(file, line) { function get_line(file, line) {
var text = filecache[file]; var text = filecache[file];
@ -227,17 +197,6 @@ profile.stop_cpu_instr = function () {
return; return;
}; };
profile.best_t = function (t) {
var qq = 0;
while (t > 1000 && qq < t_units.length - 1) {
t /= 1000;
qq++;
}
return `${t.toPrecision(4)} ${t_units[qq]}`;
};
/* /*
Frame averages are an instrumented profiling technique. Place frame() calls Frame averages are an instrumented profiling technique. Place frame() calls
in your code to get a call graph for things you are interested in. in your code to get a call graph for things you are interested in.

View file

@ -6,6 +6,7 @@ render.doc = {
var cur = {}; var cur = {};
cur.images = []; cur.images = [];
cur.samplers = [];
// When changing a shader, everything must wipe // When changing a shader, everything must wipe
render.use_shader = function use_shader(shader) { render.use_shader = function use_shader(shader) {
@ -28,10 +29,16 @@ render.use_mat = function use_mat(mat) {
cur.mat = mat; cur.mat = mat;
cur.images.length = 0; cur.images.length = 0;
cur.samplers.length = 0;
if (!cur.shader.fs.images) return; if (!cur.shader.fs.images) return;
for (var img of cur.shader.fs.images) for (var img of cur.shader.fs.images) {
if (mat[img.name]) cur.images.push(mat[img.name]); if (mat[img.name]) cur.images.push(mat[img.name]);
else cur.images.push(game.texture("icons/no_tex.gif")); else cur.images.push(game.texture("icons/no_tex.gif"));
}
for (var smp of cur.shader.fs.samplers) {
var std = smp.sampler_type === "nonfiltering";
cur.samplers.push(std);
}
}; };
var models_array = []; var models_array = [];
@ -377,28 +384,27 @@ function shader_apply_material(shader, material = {}, old = {}) {
} }
// Creates a binding object for a given mesh and shader // Creates a binding object for a given mesh and shader
var bindcache = {};
var bcache = new WeakMap(); var bcache = new WeakMap();
function sg_bind(mesh, ssbo) { function sg_bind(mesh, ssbo) {
if (cur.mesh === mesh && cur.ssbo === ssbo) { if (cur.mesh === mesh && cur.ssbo === ssbo) {
cur.bind.ssbo = [ssbo]; cur.bind.ssbo = [ssbo];
cur.bind.images = cur.images; cur.bind.images = cur.images;
cur.bind.samplers = cur.samplers;
render.setbind(cur.bind); render.setbind(cur.bind);
return; return;
} }
// var sid = os.value_id(cur.shader);
// var mid = os.value_id(mesh); /* if (bcache.has(cur.shader) && bcache.get(cur.shader).has(mesh)) {
if (bcache.has(cur.shader) && bcache.get(cur.shader).has(mesh)) {
cur.bind = bcache.get(cur.shader).get(mesh); cur.bind = bcache.get(cur.shader).get(mesh);
cur.bind.images = cur.images; cur.bind.images = cur.images;
cur.bind.samplers = cur.samplers;
if (ssbo) if (ssbo)
cur.bind.ssbo = [ssbo]; cur.bind.ssbo = [ssbo];
render.setbind(cur.bind); render.setbind(cur.bind);
return; return;
} }*/
var bind = {}; var bind = {};/* if (!bcache.has(cur.shader)) bcache.set(cur.shader, new WeakMap());
if (!bcache.has(cur.shader)) bcache.set(cur.shader, new WeakMap()); if (!bcache.get(cur.shader).has(mesh)) bcache.get(cur.shader).set(mesh, bind);*/
if (!bcache.get(cur.shader).has(mesh)) bcache.get(cur.shader).set(mesh, bind);
cur.mesh = mesh; cur.mesh = mesh;
cur.ssbo = ssbo; cur.ssbo = ssbo;
cur.bind = bind; cur.bind = bind;
@ -420,6 +426,7 @@ function sg_bind(mesh, ssbo) {
if (cur.shader.vs.storage_buffers) for (var b of cur.shader.vs.storage_buffers) bind.ssbo.push(ssbo); if (cur.shader.vs.storage_buffers) for (var b of cur.shader.vs.storage_buffers) bind.ssbo.push(ssbo);
bind.images = cur.images; bind.images = cur.images;
bind.samplers = cur.samplers;
render.setbind(cur.bind); render.setbind(cur.bind);
@ -1033,6 +1040,20 @@ var imgui_fn = function () {
prosperon.render = function () { prosperon.render = function () {
profile.report("world"); profile.report("world");
render.set_camera(prosperon.camera); render.set_camera(prosperon.camera);
// figure out the highest resolution we can render at that's an integer
var basesize = prosperon.camera.size.slice();
var baseview = prosperon.camera.view();
var wh = [baseview[2]-baseview[0], baseview[3]-baseview[1]];
var mult = 1;
var trysize = basesize.scale(mult);
while (trysize.x <= wh.x && trysize.y <= wh.y) {
mult++;
trysize = basesize.scale(mult);
}
if (Math.abs(wh.x - basesize.scale(mult-1).x) < Math.abs(wh.x - trysize.x))
mult--;
prosperon.window_render(basesize.scale(mult));
profile.report("sprites"); profile.report("sprites");
if (render.draw_sprites) render.sprites(); if (render.draw_sprites) render.sprites();
if (render.draw_particles) draw_emitters(); if (render.draw_particles) draw_emitters();
@ -1152,8 +1173,6 @@ prosperon.process = function process() {
} }
profile.report("render"); profile.report("render");
prosperon.window_render(window.size);
prosperon.render(); prosperon.render();
profile.endreport("render"); profile.endreport("render");
profile.pushdata(profile.data.cpu.render, profile.now() - sst); profile.pushdata(profile.data.cpu.render, profile.now() - sst);

View file

@ -47,6 +47,8 @@ in vec4 color0;
out vec4 color; out vec4 color;
texture2D text; texture2D text;
@sampler_type smp nonfiltering
sampler smp; sampler smp;
@include_block frag @include_block frag

View file

@ -23,9 +23,9 @@ out vec4 color;
#define PI 3.141592 #define PI 3.141592
@image_sample_type diffuse unfilterable_float
texture2D diffuse; texture2D diffuse;
@sampler_type smp nonfiltering
@sampler_type smp filtering
sampler smp; sampler smp;
uniform vec2 mouse; uniform vec2 mouse;

View file

@ -44,6 +44,8 @@ in vec4 shade;
out vec4 color; out vec4 color;
texture2D diffuse; texture2D diffuse;
@sampler_type smp nonfiltering
sampler smp; sampler smp;
void frag() void frag()

View file

@ -723,9 +723,11 @@ sg_bindings js2bind(JSValue v)
bind.index_buffer = *js2sg_buffer(index); bind.index_buffer = *js2sg_buffer(index);
JSValue imgs = js_getpropstr(v, "images"); JSValue imgs = js_getpropstr(v, "images");
JSValue samplers = js_getpropstr(v, "samplers");
for (int i = 0; i < js_arrlen(imgs); i++) { for (int i = 0; i < js_arrlen(imgs); i++) {
bind.fs.images[i] = js2texture(js_getpropidx(imgs, i))->id; bind.fs.images[i] = js2texture(js_getpropidx(imgs, i))->id;
bind.fs.samplers[i] = std_sampler; int use_std = js2boolean(js_getpropidx(samplers, i));
bind.fs.samplers[i] = use_std ? std_sampler : tex_sampler;
} }
JSValue ssbo = js_getpropstr(v, "ssbo"); JSValue ssbo = js_getpropstr(v, "ssbo");
@ -766,7 +768,6 @@ JSC_CCALL(render_glue_pass,
// Set the portion of the window to be rendered to // Set the portion of the window to be rendered to
JSC_CCALL(render_viewport, JSC_CCALL(render_viewport,
sg_apply_viewportf(js2number(argv[0]), js2number(argv[1]), js2number(argv[2]), js2number(argv[3]), 0); sg_apply_viewportf(js2number(argv[0]), js2number(argv[1]), js2number(argv[2]), js2number(argv[3]), 0);
// sgl_viewportf(js2number(argv[0]), js2number(argv[1]), js2number(argv[2]), js2number(argv[3]), 0);
) )
JSC_CCALL(render_commit, sg_commit()) JSC_CCALL(render_commit, sg_commit())
@ -1848,10 +1849,26 @@ JSC_CCALL(profile_gather_stop,
JS_SetInterruptHandler(rt,NULL,NULL); JS_SetInterruptHandler(rt,NULL,NULL);
) )
JSC_CCALL(profile_best_t,
char* result[50];
double seconds = stm_sec(js2number(argv[0]));
if (seconds < 1e-6)
snprintf(result, 50, "%.2f ns", seconds * 1e9);
else if (seconds < 1e-3)
snprintf(result, 50, "%.2f µs", seconds * 1e6);
else if (seconds < 1)
snprintf(result, 50, "%.2f ms", seconds * 1e3);
else
snprintf(result, 50, "%.2f s", seconds);
ret = str2js(result);
)
JSC_CCALL(profile_secs, return number2js(stm_sec(js2number(argv[0]))); ) JSC_CCALL(profile_secs, return number2js(stm_sec(js2number(argv[0]))); )
static const JSCFunctionListEntry js_profile_funcs[] = { static const JSCFunctionListEntry js_profile_funcs[] = {
MIST_FUNC_DEF(profile,now,0), MIST_FUNC_DEF(profile,now,0),
MIST_FUNC_DEF(profile,best_t, 1),
MIST_FUNC_DEF(profile,gather,2), MIST_FUNC_DEF(profile,gather,2),
MIST_FUNC_DEF(profile,gather_rate,1), MIST_FUNC_DEF(profile,gather_rate,1),
MIST_FUNC_DEF(profile,gather_stop,0), MIST_FUNC_DEF(profile,gather_stop,0),

View file

@ -152,9 +152,9 @@ void render_init() {
.image_pool_size = 1024, .image_pool_size = 1024,
}); });
// sgl_setup(&(sgl_desc_t){ #ifndef NDEBUG
// .logger.func = sg_logging sg_trace_hooks hh = sg_install_trace_hooks(&hooks);
// }); #endif
std_sampler = sg_make_sampler(&(sg_sampler_desc){}); std_sampler = sg_make_sampler(&(sg_sampler_desc){});
tex_sampler = sg_make_sampler(&(sg_sampler_desc){ tex_sampler = sg_make_sampler(&(sg_sampler_desc){
@ -165,10 +165,6 @@ void render_init() {
.wrap_v = SG_WRAP_REPEAT .wrap_v = SG_WRAP_REPEAT
}); });
#ifndef NDEBUG
sg_trace_hooks hh = sg_install_trace_hooks(&hooks);
#endif
sg_features feat = sg_query_features(); sg_features feat = sg_query_features();
TOPLEFT = feat.origin_top_left; TOPLEFT = feat.origin_top_left;