no libc, start on socket x11
This commit is contained in:
+3
-2
@@ -5,8 +5,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <tgmath.h>
|
||||
|
||||
void *com_std_realloc(void *ptr, size_t size) { return realloc(ptr, size); }
|
||||
void com_std_free(void *ptr) { free(ptr); }
|
||||
void *com_std_alloc(void *ptr, size_t size) {
|
||||
return size != 0 ? realloc(ptr, size) : (free(ptr), NULL);
|
||||
}
|
||||
void com_std_assert(bool holds) { assert(holds); }
|
||||
void com_std_printf(char const *fmt, ...) {
|
||||
va_list args;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "../std.h"
|
||||
#include <stdarg.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
static inline long com_std_syscall(long number, long arg1, long arg2,
|
||||
long arg3) {
|
||||
long ret;
|
||||
__asm__ volatile("syscall"
|
||||
: "=a"(ret)
|
||||
: "a"(number), "D"(arg1), "S"(arg2), "d"(arg3)
|
||||
: "rcx", "r11", "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *com_std_alloc(void *ptr, size_t size) { return NULL; }
|
||||
void com_std_assert(bool holds) {
|
||||
/* TODO: Write line info to stderr as well. */
|
||||
if (!holds)
|
||||
com_std_syscall(__NR_exit, -1, 0, 0);
|
||||
}
|
||||
|
||||
/* TODO: Figure out a way to make it easy to deal with. */
|
||||
void com_std_printf(char const *fmt, ...) {
|
||||
// va_list args;
|
||||
// va_start(args, fmt);
|
||||
// vprintf(fmt, args);
|
||||
// va_end(args);
|
||||
}
|
||||
|
||||
double com_std_sqrt(double v) { return __builtin_sqrt(v); }
|
||||
double com_std_fabs(double v) { return __builtin_fabs(v); }
|
||||
double com_std_sin(double v) { return __builtin_sin(v); }
|
||||
double com_std_cos(double v) { return __builtin_cos(v); }
|
||||
+6
-6
@@ -1,10 +1,10 @@
|
||||
#include "../std.h"
|
||||
|
||||
void *com_std_realloc(void *ptr, size_t size) { return NULL; }
|
||||
void com_std_free(void *ptr) {}
|
||||
void *com_std_alloc(void *ptr, size_t size) { return NULL; }
|
||||
void com_std_assert(bool holds) {}
|
||||
void com_std_printf(char const *fmt, ...) {}
|
||||
double com_std_sqrt(double v) { return 0; }
|
||||
double com_std_fabs(double v) { return 0; }
|
||||
double com_std_sin(double v) { return 0; }
|
||||
double com_std_cos(double v) { return 0; }
|
||||
|
||||
double com_std_sqrt(double v) { return __builtin_sqrt(v); }
|
||||
double com_std_fabs(double v) { return __builtin_fabs(v); }
|
||||
double com_std_sin(double v) { return __builtin_sin(v); }
|
||||
double com_std_cos(double v) { return __builtin_cos(v); }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "../std.h"
|
||||
#include "timer.h"
|
||||
#include "../time.h"
|
||||
#include <stdint.h>
|
||||
#define __USE_POSIX199309 1
|
||||
#include <time.h>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "time.h"
|
||||
#include <stdint.h>
|
||||
|
||||
uint64_t com_timer_count_ns(void) { return 0; }
|
||||
|
||||
void com_timer_profile(uint64_t starttime, const char *what) {
|
||||
(void)starttime;
|
||||
(void)what;
|
||||
}
|
||||
+69
-69
@@ -4,9 +4,9 @@
|
||||
*/
|
||||
|
||||
#include "fix.h"
|
||||
#include "Timer/timer.h"
|
||||
#include "def.h"
|
||||
#include "std.h"
|
||||
#include "time.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -128,75 +128,75 @@ void com_fix_run_bench(void) {
|
||||
}
|
||||
|
||||
void com_fix_run_tests(void) {
|
||||
{
|
||||
double max_sqrt_deviation = 0.0f;
|
||||
com_fix_t sqrt_accumulator = 0;
|
||||
com_fix_t sqrt_test_step = COM_FIX_FRACUNIT >> 2; /* Quarter step */
|
||||
for (int i = 0; i < COM_FIX_FRACUNIT << 1; ++i) {
|
||||
com_fix_t sqrt = com_fix_sqrt(sqrt_accumulator);
|
||||
double const deviation =
|
||||
com_std_sqrt(com_fix_as_float(sqrt_accumulator)) -
|
||||
com_fix_as_float(sqrt);
|
||||
if (deviation > max_sqrt_deviation)
|
||||
max_sqrt_deviation = deviation;
|
||||
sqrt_accumulator += sqrt_test_step;
|
||||
}
|
||||
com_std_printf("max sqrt deviation: %f\n", max_sqrt_deviation);
|
||||
}
|
||||
// {
|
||||
// double max_sqrt_deviation = 0.0f;
|
||||
// com_fix_t sqrt_accumulator = 0;
|
||||
// com_fix_t sqrt_test_step = COM_FIX_FRACUNIT >> 2; /* Quarter step */
|
||||
// for (int i = 0; i < COM_FIX_FRACUNIT << 1; ++i) {
|
||||
// com_fix_t sqrt = com_fix_sqrt(sqrt_accumulator);
|
||||
// double const deviation =
|
||||
// com_std_sqrt(com_fix_as_float(sqrt_accumulator)) -
|
||||
// com_fix_as_float(sqrt);
|
||||
// if (deviation > max_sqrt_deviation)
|
||||
// max_sqrt_deviation = deviation;
|
||||
// sqrt_accumulator += sqrt_test_step;
|
||||
// }
|
||||
// com_std_printf("max sqrt deviation: %f\n", max_sqrt_deviation);
|
||||
// }
|
||||
|
||||
{
|
||||
double max_sin_deviation = 0.0f;
|
||||
com_fix_t sin_accumulator = -COM_FIX_PI * 4;
|
||||
com_fix_t sin_test_step = (COM_FIX_PI << 1) >> 10;
|
||||
for (int i = 0; i < 1024 * 32; ++i) {
|
||||
com_fix_t sin = com_fix_sin(sin_accumulator);
|
||||
double const deviation =
|
||||
com_std_fabs(com_std_sin(com_fix_as_float(sin_accumulator)) -
|
||||
com_fix_as_float(sin));
|
||||
if (deviation > max_sin_deviation)
|
||||
max_sin_deviation = deviation;
|
||||
sin_accumulator += sin_test_step;
|
||||
}
|
||||
com_std_printf("max sin deviation: %f\n", max_sin_deviation);
|
||||
}
|
||||
// {
|
||||
// double max_sin_deviation = 0.0f;
|
||||
// com_fix_t sin_accumulator = -COM_FIX_PI * 4;
|
||||
// com_fix_t sin_test_step = (COM_FIX_PI << 1) >> 10;
|
||||
// for (int i = 0; i < 1024 * 32; ++i) {
|
||||
// com_fix_t sin = com_fix_sin(sin_accumulator);
|
||||
// double const deviation =
|
||||
// com_std_fabs(com_std_sin(com_fix_as_float(sin_accumulator)) -
|
||||
// com_fix_as_float(sin));
|
||||
// if (deviation > max_sin_deviation)
|
||||
// max_sin_deviation = deviation;
|
||||
// sin_accumulator += sin_test_step;
|
||||
// }
|
||||
// com_std_printf("max sin deviation: %f\n", max_sin_deviation);
|
||||
// }
|
||||
|
||||
{
|
||||
double max_cos_deviation = 0.0f;
|
||||
com_fix_t cos_accumulator = -COM_FIX_PI * 4;
|
||||
com_fix_t cos_test_step = (COM_FIX_PI << 1) >> 10;
|
||||
for (int i = 0; i < 1024 * 32; ++i) {
|
||||
com_fix_t cos = com_fix_cos(cos_accumulator);
|
||||
double const deviation =
|
||||
com_std_fabs(com_std_cos(com_fix_as_float(cos_accumulator)) -
|
||||
com_fix_as_float(cos));
|
||||
if (deviation > max_cos_deviation)
|
||||
max_cos_deviation = deviation;
|
||||
cos_accumulator += cos_test_step;
|
||||
}
|
||||
com_std_printf("max cos deviation: %f\n", max_cos_deviation);
|
||||
}
|
||||
// {
|
||||
// double max_cos_deviation = 0.0f;
|
||||
// com_fix_t cos_accumulator = -COM_FIX_PI * 4;
|
||||
// com_fix_t cos_test_step = (COM_FIX_PI << 1) >> 10;
|
||||
// for (int i = 0; i < 1024 * 32; ++i) {
|
||||
// com_fix_t cos = com_fix_cos(cos_accumulator);
|
||||
// double const deviation =
|
||||
// com_std_fabs(com_std_cos(com_fix_as_float(cos_accumulator)) -
|
||||
// com_fix_as_float(cos));
|
||||
// if (deviation > max_cos_deviation)
|
||||
// max_cos_deviation = deviation;
|
||||
// cos_accumulator += cos_test_step;
|
||||
// }
|
||||
// com_std_printf("max cos deviation: %f\n", max_cos_deviation);
|
||||
// }
|
||||
|
||||
{
|
||||
double max_sin_deviation = 0.0f;
|
||||
double max_cos_deviation = 0.0f;
|
||||
com_fix_t sincos_accumulator = -COM_FIX_PI * 4;
|
||||
com_fix_t sincos_test_step = (COM_FIX_PI << 1) >> 10;
|
||||
for (int i = 0; i < 1024 * 32; ++i) {
|
||||
com_fix_t sin, cos;
|
||||
com_fix_sincos(sincos_accumulator, &sin, &cos);
|
||||
double const sin_deviation =
|
||||
com_std_fabs(com_std_sin(com_fix_as_float(sincos_accumulator)) -
|
||||
com_fix_as_float(sin));
|
||||
double const cos_deviation =
|
||||
com_std_fabs(com_std_cos(com_fix_as_float(sincos_accumulator)) -
|
||||
com_fix_as_float(cos));
|
||||
if (sin_deviation > max_sin_deviation)
|
||||
max_sin_deviation = sin_deviation;
|
||||
if (cos_deviation > max_cos_deviation)
|
||||
max_cos_deviation = cos_deviation;
|
||||
sincos_accumulator += sincos_test_step;
|
||||
}
|
||||
com_std_printf("max sincos deviations: %f %f\n", max_sin_deviation,
|
||||
max_cos_deviation);
|
||||
}
|
||||
// {
|
||||
// double max_sin_deviation = 0.0f;
|
||||
// double max_cos_deviation = 0.0f;
|
||||
// com_fix_t sincos_accumulator = -COM_FIX_PI * 4;
|
||||
// com_fix_t sincos_test_step = (COM_FIX_PI << 1) >> 10;
|
||||
// for (int i = 0; i < 1024 * 32; ++i) {
|
||||
// com_fix_t sin, cos;
|
||||
// com_fix_sincos(sincos_accumulator, &sin, &cos);
|
||||
// double const sin_deviation =
|
||||
// com_std_fabs(com_std_sin(com_fix_as_float(sincos_accumulator)) -
|
||||
// com_fix_as_float(sin));
|
||||
// double const cos_deviation =
|
||||
// com_std_fabs(com_std_cos(com_fix_as_float(sincos_accumulator)) -
|
||||
// com_fix_as_float(cos));
|
||||
// if (sin_deviation > max_sin_deviation)
|
||||
// max_sin_deviation = sin_deviation;
|
||||
// if (cos_deviation > max_cos_deviation)
|
||||
// max_cos_deviation = cos_deviation;
|
||||
// sincos_accumulator += sincos_test_step;
|
||||
// }
|
||||
// com_std_printf("max sincos deviations: %f %f\n", max_sin_deviation,
|
||||
// max_cos_deviation);
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -32,6 +32,10 @@ static inline com_fix_t com_fix_add(com_fix_t a, com_fix_t b) { return a + b; }
|
||||
|
||||
static inline com_fix_t com_fix_sub(com_fix_t a, com_fix_t b) { return a - b; }
|
||||
|
||||
static inline com_fix_t com_fix_int(com_fix_t a) {
|
||||
return a >> COM_FIX_FRACBITS;
|
||||
}
|
||||
|
||||
static inline com_fix_t com_fix_mul(com_fix_t a, com_fix_t b) {
|
||||
return (com_fix_t)(((int64_t)a * (int64_t)b) >> COM_FIX_FRACBITS);
|
||||
}
|
||||
|
||||
+126
-14
@@ -9,7 +9,9 @@
|
||||
#include "mat.h"
|
||||
#include "pnt.h"
|
||||
#include "vec.h"
|
||||
#include "zord.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Projects vertex position to a clip space via reordered row-major MVP matrix.
|
||||
It skips calculation of z depth component, as we assume to never use it.
|
||||
@@ -46,17 +48,29 @@ static inline com_vec_t com_gem_vec_project_clip(com_mat_t a, com_vec_t b) {
|
||||
#define COM_GEM_VERTEX_UNCLIPPED (0 << 0)
|
||||
#define COM_GEM_VERTEX_CLIPPED_X (1 << 0)
|
||||
#define COM_GEM_VERTEX_CLIPPED_Y (1 << 1)
|
||||
/* Attempt to project clip space vertex to NDC, reporting which component lies
|
||||
* outside of view. Bit test against those per component. This is needed for
|
||||
* determining new view-lying clipped triangles. */
|
||||
/* Attempt to project clip space vertex to render pixel space, reporting which
|
||||
* component lies outside of view. Bit test against those per component. This is
|
||||
* needed for determining new view-lying clipped triangles. */
|
||||
static inline uint8_t com_gem_clip_vis_project(com_vec_t a, com_pnt_t *out) {
|
||||
uint8_t mask = 0;
|
||||
if (a.a[0] < -a.a[2] || a.a[0] > a.a[2])
|
||||
mask ^= COM_GEM_VERTEX_CLIPPED_X;
|
||||
if (a.a[1] < -a.a[2] || a.a[1] > a.a[2])
|
||||
mask ^= COM_GEM_VERTEX_CLIPPED_Y;
|
||||
out->a[0] = com_fix_div(a.a[0], a.a[2]) / 480 + 240;
|
||||
out->a[1] = com_fix_div(a.a[1], a.a[2]) / 640 + 320;
|
||||
// out->a[0] = com_fix_mul((com_fix_div(a.a[0], a.a[2]) + COM_FIX_FRACUNIT) >>
|
||||
// 1,
|
||||
// 640 * COM_FIX_FRACUNIT);
|
||||
// out->a[1] = com_fix_mul((com_fix_div(a.a[1], a.a[2]) + COM_FIX_FRACUNIT) >>
|
||||
// 1,
|
||||
// 480 * COM_FIX_FRACUNIT);
|
||||
out->a[0] =
|
||||
(com_fix_mul(com_fix_div(a.a[0], a.a[2]), 640 * COM_FIX_FRACUNIT) >>
|
||||
COM_FIX_FRACBITS) +
|
||||
320;
|
||||
out->a[1] =
|
||||
(com_fix_mul(com_fix_div(a.a[1], a.a[2]), 480 * COM_FIX_FRACUNIT) >>
|
||||
COM_FIX_FRACBITS) +
|
||||
240;
|
||||
return mask;
|
||||
}
|
||||
|
||||
@@ -75,7 +89,7 @@ static inline void com_gem_draw_triangle(com_pnt_t v0, com_pnt_t v1,
|
||||
com_vec_t ws = com_pnt_edge_weight(v0, v1, v2, p);
|
||||
|
||||
// If the point is inside or on all edges, draw the pixel
|
||||
// (Assumes Clockwise vertex ordering)
|
||||
// (Assumes Counter Clockwise vertex ordering)
|
||||
if (ws.a[0] >= 0 && ws.a[1] >= 0 && ws.a[2] >= 0) {
|
||||
out[(y * 640 + x) * 4 + 0] = 125;
|
||||
out[(y * 640 + x) * 4 + 1] = 125;
|
||||
@@ -85,10 +99,15 @@ static inline void com_gem_draw_triangle(com_pnt_t v0, com_pnt_t v1,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void com_gem_draw_triangle_textured(com_pnt_t v0, com_pnt_t v1,
|
||||
com_pnt_t v2, uint8_t *out,
|
||||
com_pnt_t uv0, com_pnt_t uv1,
|
||||
com_pnt_t uv2, uint8_t *tex) {
|
||||
/* TODO: Implement and compare:
|
||||
https://www.digipen.edu/sites/default/files/public/docs/theses/salem-haykal-digipen-master-of-science-in-computer-science-thesis-an-optimized-triangle-rasterizer.pdf
|
||||
|
||||
Tile-based variant fares even worse than this implementation.
|
||||
*/
|
||||
static inline void
|
||||
com_gem_draw_triangle_textured_edge(com_pnt_t v0, com_pnt_t v1, com_pnt_t v2,
|
||||
uint8_t *out, com_pnt_t uv0, com_pnt_t uv1,
|
||||
com_pnt_t uv2, uint8_t *tex) {
|
||||
int minX = com_vec_min(com_vec_from(v0.a[0], v1.a[0], v2.a[0]));
|
||||
int minY = com_vec_min(com_vec_from(v0.a[1], v1.a[1], v2.a[1]));
|
||||
int maxX = com_vec_max(com_vec_from(v0.a[0], v1.a[0], v2.a[0]));
|
||||
@@ -100,7 +119,6 @@ static inline void com_gem_draw_triangle_textured(com_pnt_t v0, com_pnt_t v1,
|
||||
for (int x = minX; x <= maxX; x++) {
|
||||
com_pnt_t p = {.a = {x, y}};
|
||||
|
||||
/* TODO: Move to a separate weighting function over vec. */
|
||||
// Test the pixel center against all 3 edges
|
||||
com_vec_t ws = com_pnt_edge_weight(v0, v1, v2, p);
|
||||
|
||||
@@ -124,12 +142,106 @@ static inline void com_gem_draw_triangle_textured(com_pnt_t v0, com_pnt_t v1,
|
||||
int32_t ty =
|
||||
(int32_t)((v + (COM_FIX_FRACUNIT / 2)) / (COM_FIX_FRACUNIT / 16));
|
||||
|
||||
out[(y * 640 + x) * 4 + 0] = tex[(ty * 32 + tx) * 3 + 0];
|
||||
out[(y * 640 + x) * 4 + 1] = tex[(ty * 32 + tx) * 3 + 1];
|
||||
out[(y * 640 + x) * 4 + 2] = tex[(ty * 32 + tx) * 3 + 2];
|
||||
// uint32_t idx = com_zord_order(tx, ty);
|
||||
uint32_t idx = ty * 32 + tx;
|
||||
// uint32_t bidx = com_zord_order(x, y);
|
||||
uint32_t bidx = y * 640 + x;
|
||||
|
||||
out[bidx * 4 + 0] = tex[idx * 3 + 0];
|
||||
out[bidx * 4 + 1] = tex[idx * 3 + 1];
|
||||
out[bidx * 4 + 2] = tex[idx * 3 + 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void draw_span(int32_t x_start_fp, int32_t x_end_fp, int y,
|
||||
uint8_t *out, uint8_t *tex) {
|
||||
int x1 = com_fix_int(
|
||||
x_start_fp + (1 << (COM_FIX_FRACBITS - 1))); // Rounding to nearest pixel
|
||||
int x2 = com_fix_int(x_end_fp + (1 << (COM_FIX_FRACBITS - 1)));
|
||||
|
||||
if (x1 > x2) {
|
||||
int tmp = x1;
|
||||
x1 = x2;
|
||||
x2 = tmp;
|
||||
}
|
||||
|
||||
for (int x = x1; x < x2; x++) {
|
||||
uint32_t idx = 0 * 32 + 0;
|
||||
uint32_t bidx = y * 640 + x;
|
||||
out[bidx * 4 + 0] = tex[idx * 3 + 0];
|
||||
out[bidx * 4 + 1] = tex[idx * 3 + 1];
|
||||
out[bidx * 4 + 2] = tex[idx * 3 + 2];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
com_gem_draw_triangle_textured_span(com_pnt_t v0, com_pnt_t v1, com_pnt_t v2,
|
||||
uint8_t *out, com_pnt_t uv0, com_pnt_t uv1,
|
||||
com_pnt_t uv2, uint8_t *tex) {
|
||||
// 1. Sort vertices by Y coordinate (v0.a[1] <= v1.a[1] <= v2.a[1])
|
||||
if (v0.a[1] > v1.a[1]) {
|
||||
com_pnt_t tmp = v0;
|
||||
v0 = v1;
|
||||
v1 = tmp;
|
||||
}
|
||||
if (v0.a[1] > v2.a[1]) {
|
||||
com_pnt_t tmp = v0;
|
||||
v0 = v2;
|
||||
v2 = tmp;
|
||||
}
|
||||
if (v1.a[1] > v2.a[1]) {
|
||||
com_pnt_t tmp = v1;
|
||||
v1 = v2;
|
||||
v2 = tmp;
|
||||
}
|
||||
|
||||
// Guard against zero-height triangles
|
||||
if ((int)v0.a[1] == (int)v2.a[1])
|
||||
return;
|
||||
|
||||
// 2. Compute overall inverse slopes (dX/dY) for all edges
|
||||
// Fixed-point division is performed using 64-bit integer casting to prevent
|
||||
// overflow
|
||||
com_fix_t dx02 = (v2.a[1] != v0.a[1])
|
||||
? (com_fix_t)((int64_t)(v2.a[0] - v0.a[0])
|
||||
<< COM_FIX_FRACBITS / (v2.a[1] - v0.a[1]))
|
||||
: 0;
|
||||
com_fix_t dx01 = (v1.a[1] != v0.a[1])
|
||||
? (com_fix_t)((int64_t)(v1.a[0] - v0.a[0])
|
||||
<< COM_FIX_FRACBITS / (v1.a[1] - v0.a[1]))
|
||||
: 0;
|
||||
com_fix_t dx12 = (v2.a[1] != v1.a[1])
|
||||
? (com_fix_t)((int64_t)(v2.a[0] - v1.a[0])
|
||||
<< COM_FIX_FRACBITS / (v2.a[1] - v1.a[1]))
|
||||
: 0;
|
||||
|
||||
// Determine the scanline limits (pixel discrete boundaries)
|
||||
int y_start = com_fix_int(v0.a[1]);
|
||||
int y_mid = com_fix_int(v1.a[1]);
|
||||
int y_end = com_fix_int(v2.a[1]);
|
||||
|
||||
// Initialize edge walkers starting at the top vertex (v0)
|
||||
com_fix_t edge1 = v0.a[0]; // Follows the long edge (v0 -> v2)
|
||||
com_fix_t edge2 = v0.a[0]; // Follows short edges (v0 -> v1, then v1 -> v2)
|
||||
|
||||
// 3. Top Half Scan: Walk from top vertex to middle vertex breakpoint
|
||||
for (int y = y_start; y < y_mid; y++) {
|
||||
draw_span(edge1, edge2, y, out, tex);
|
||||
edge1 += dx02;
|
||||
edge2 += dx01;
|
||||
}
|
||||
|
||||
// Adjust the short edge walker directly to the middle vertex position
|
||||
edge2 = v1.a[0];
|
||||
|
||||
// 4. Bottom Half Scan: Walk from middle vertex to bottom vertex
|
||||
for (int y = y_mid; y < y_end; y++) {
|
||||
draw_span(edge1, edge2, y, out, tex);
|
||||
edge1 += dx02;
|
||||
edge2 += dx12;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+6
-7
@@ -44,9 +44,9 @@ struct com_lzw_table com_lzw_infer_table(const char *datain, uint32_t sizein) {
|
||||
if (!code_found) {
|
||||
if (table_size >= table_cap) {
|
||||
/* TODO: Ref to prev table gets missed, memory leak scenario */
|
||||
if (!(table = com_std_realloc(
|
||||
table, sizeof(struct com_lzw_table_entry) *
|
||||
(table_cap + COM_LZW_TABLE_CAP_GROW))))
|
||||
if (!(table = com_std_alloc(table,
|
||||
sizeof(struct com_lzw_table_entry) *
|
||||
(table_cap + COM_LZW_TABLE_CAP_GROW))))
|
||||
goto ERR_ALLOC_INIT_TABLE;
|
||||
|
||||
table_cap += COM_LZW_TABLE_CAP_GROW;
|
||||
@@ -68,14 +68,14 @@ struct com_lzw_table com_lzw_infer_table(const char *datain, uint32_t sizein) {
|
||||
|
||||
ERR_ALLOC_INIT_TABLE:
|
||||
if (table_cap > 0)
|
||||
com_std_free(table);
|
||||
com_std_alloc(table, 0);
|
||||
return (struct com_lzw_table){0};
|
||||
}
|
||||
|
||||
void com_lzw_free_table(struct com_lzw_table *table) {
|
||||
if (!table->table)
|
||||
return;
|
||||
com_std_free(table->table);
|
||||
com_std_alloc(table->table, 0);
|
||||
table->size = 0;
|
||||
table->cap = 0;
|
||||
table->init_size = 0;
|
||||
@@ -131,8 +131,7 @@ bool com_lzw_compress(const struct com_lzw_table *table, const char *datain,
|
||||
|
||||
if (output_size == output_cap && output_bitshift + codesize > 8) {
|
||||
/* TODO: catch alloc failure */
|
||||
output =
|
||||
com_std_realloc(output, output_cap + COM_LZW_OUTPUT_CAP_GROWTH);
|
||||
output = com_std_alloc(output, output_cap + COM_LZW_OUTPUT_CAP_GROWTH);
|
||||
output_cap += COM_LZW_OUTPUT_CAP_GROWTH;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#include "mat.h"
|
||||
#include "Timer/timer.h"
|
||||
#include "time.h"
|
||||
|
||||
/* TODO: Doesn't work, clang optimizes it away. We need RNG here. */
|
||||
|
||||
|
||||
+2
-1
@@ -150,7 +150,8 @@ static inline com_mat_t com_mat_look_at(com_vec_t pos, com_vec_t up,
|
||||
return result;
|
||||
}
|
||||
|
||||
/* TODO: move to .c file */
|
||||
/* TODO: Make sure it's compile time optimized, as all parameters are constant.
|
||||
*/
|
||||
/* Produces a projection matrix needed for camera work. */
|
||||
static inline com_mat_t com_mat_perspective(uint16_t rwidth, uint16_t rheight,
|
||||
com_fix_t nearz, com_fix_t farz,
|
||||
|
||||
+30
-2
@@ -63,11 +63,13 @@ static inline com_fix_t com_pnt_max(com_pnt_t a) {
|
||||
return com_fix_max(a.a[0], a.a[1]);
|
||||
}
|
||||
|
||||
/* TODO: Safeguard by com_fix_mul()? */
|
||||
/* Tests whether a point is lying right to a line produced by l0 and l1.
|
||||
This assumes that l0 and l1 are in clockwise order.
|
||||
Result is positive or zero if it holds true, otherwise it's negative.
|
||||
This also produces area of a triangle! */
|
||||
This also produces area of a triangle!
|
||||
|
||||
Somehow this is faster than counter clockwise ordering? In case tested.
|
||||
*/
|
||||
static inline com_fix_t com_pnt_edge_orient(com_pnt_t l0, com_pnt_t l1,
|
||||
com_pnt_t p) {
|
||||
return (l0.a[0] - l1.a[0]) * (p.a[1] - l1.a[1]) -
|
||||
@@ -83,6 +85,32 @@ static inline com_vec_t com_pnt_edge_weight(com_pnt_t v0, com_pnt_t v1,
|
||||
com_pnt_edge_orient(v0, v1, p)}};
|
||||
}
|
||||
|
||||
/* As terms are constant over pixel steps, we can use precalculated values.
|
||||
See: (l0.a[0] - l1.a[0]) and (l0.a[1] - l1.a[1])
|
||||
|
||||
Optimizer seems to be smart enough to figure this out already? And even more
|
||||
optimal. Delete this later.
|
||||
*/
|
||||
static inline void com_pnt_edge_weight_calc_precomp_table(com_pnt_t v0,
|
||||
com_pnt_t v1,
|
||||
com_pnt_t v2,
|
||||
com_pnt_t out[3]) {
|
||||
out[0] = com_pnt_sub(v1, v2);
|
||||
out[1] = com_pnt_sub(v2, v0);
|
||||
out[2] = com_pnt_sub(v0, v1);
|
||||
}
|
||||
|
||||
static inline com_vec_t
|
||||
com_pnt_edge_weight_calc_precomp(com_pnt_t v0, com_pnt_t v1, com_pnt_t v2,
|
||||
com_pnt_t p, com_pnt_t precomp[3]) {
|
||||
return (com_vec_t){.a = {precomp[0].a[0] * (p.a[1] - v2.a[1]) -
|
||||
precomp[0].a[1] * (p.a[0] - v2.a[0]),
|
||||
precomp[1].a[0] * (p.a[1] - v0.a[1]) -
|
||||
precomp[1].a[1] * (p.a[0] - v0.a[0]),
|
||||
precomp[2].a[0] * (p.a[1] - v0.a[1]) -
|
||||
precomp[2].a[1] * (p.a[0] - v0.a[0])}};
|
||||
}
|
||||
|
||||
static inline void com_pnt_print(com_pnt_t a) {
|
||||
com_fix_print(a.a[0]);
|
||||
com_fix_print(a.a[1]);
|
||||
|
||||
+8
-3
@@ -3,13 +3,16 @@
|
||||
even memory mnagement.
|
||||
*/
|
||||
|
||||
#ifndef COM_STD_H
|
||||
#define COM_STD_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
extern void *com_std_realloc(void *ptr, size_t size);
|
||||
extern void com_std_free(void *ptr);
|
||||
/* Note: Freeing is done by passing 0 size to pointer. */
|
||||
extern void *com_std_alloc(void *ptr, size_t size);
|
||||
|
||||
/* Note: Functions listed below are only available for test builds. */
|
||||
/* Note: Functions listed below are only available for dev builds. */
|
||||
/* Trigonometry functions are for reference testing of our own fixed point
|
||||
* implementations. Do not use otherwise. */
|
||||
extern void com_std_assert(bool holds);
|
||||
@@ -18,3 +21,5 @@ extern double com_std_sqrt(double v);
|
||||
extern double com_std_fabs(double v);
|
||||
extern double com_std_sin(double v);
|
||||
extern double com_std_cos(double v);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef COM_TIMER_H
|
||||
#define COM_TIMER_H
|
||||
|
||||
#include "../def.h"
|
||||
#include "def.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* Global monotonic counter, meaning it always increases. Not applicable for
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "zord.h"
|
||||
#include <stdint.h>
|
||||
|
||||
const uint16_t com_zord_morton_table[] = {
|
||||
0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040,
|
||||
0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101,
|
||||
0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144,
|
||||
0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, 0x0405,
|
||||
0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450,
|
||||
0x0451, 0x0454, 0x0455, 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511,
|
||||
0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554,
|
||||
0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015,
|
||||
0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 0x1100,
|
||||
0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141,
|
||||
0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404,
|
||||
0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, 0x1441, 0x1444, 0x1445,
|
||||
0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510,
|
||||
0x1511, 0x1514, 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551,
|
||||
0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014,
|
||||
0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055,
|
||||
0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140,
|
||||
0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, 0x4401,
|
||||
0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444,
|
||||
0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 0x4500, 0x4501, 0x4504, 0x4505,
|
||||
0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550,
|
||||
0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011,
|
||||
0x5014, 0x5015, 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054,
|
||||
0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115,
|
||||
0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400,
|
||||
0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 0x5440, 0x5441,
|
||||
0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504,
|
||||
0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545,
|
||||
0x5550, 0x5551, 0x5554, 0x5555};
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef COM_ZORD_H
|
||||
#define COM_ZORD_H
|
||||
#include <stdint.h>
|
||||
|
||||
// #include <immintrin.h>
|
||||
|
||||
extern const uint16_t com_zord_morton_table[];
|
||||
|
||||
/* Z-filling curve to help with cache and data locality. */
|
||||
static inline uint32_t com_zord_order(uint16_t x, uint16_t y) {
|
||||
return (com_zord_morton_table[y >> 8] << 17) |
|
||||
(com_zord_morton_table[x >> 8] << 16) |
|
||||
(com_zord_morton_table[y & 0xFF] << 1) |
|
||||
(com_zord_morton_table[x & 0xFF]);
|
||||
|
||||
// return _pdep_u32(x, 0x55555555) | _pdep_u32(y, 0xAAAAAAAA);
|
||||
}
|
||||
|
||||
/* https://en.wikipedia.org/wiki/Z-order_curve#Coordinate_values*/
|
||||
static inline uint32_t com_zord_inc_x(uint32_t z) {
|
||||
return (((z | 0b10101010) + 1) & 0b01010101) | (z & 0b10101010);
|
||||
}
|
||||
|
||||
static inline uint32_t com_zord_dec_x(uint32_t z) {
|
||||
return (((z & 0b01010101) - 1) & 0b01010101) | (z & 0b10101010);
|
||||
}
|
||||
|
||||
static inline uint32_t com_zord_inc_y(uint32_t z) {
|
||||
return (((z | 0b01010101) + 1) & 0b10101010) | (z & 0b01010101);
|
||||
}
|
||||
|
||||
static inline uint32_t com_zord_dec_y(uint32_t z) {
|
||||
return (((z & 0b10101010) - 1) & 0b10101010) | (z & 0b01010101);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user