Add extra constructors for initialized and zeroed arrays
authorNick Downing <nick@ndcode.org>
Tue, 19 Apr 2022 06:03:57 +0000 (16:03 +1000)
committerNick Downing <nick@ndcode.org>
Tue, 19 Apr 2022 06:03:57 +0000 (16:03 +1000)
array.h
render.c

diff --git a/array.h b/array.h
index c494403..73493a4 100644 (file)
--- a/array.h
+++ b/array.h
@@ -18,7 +18,9 @@ struct array {
   size_t dim[0];
 };
 
-static inline __attribute__((always_inline)) void *array_new(
+// following constructor is geared towards being called from array_dupN()
+// which already has the strides available, so it doesn't calculate them
+static inline __attribute__((always_inline)) struct array *array_new(
   int n_dims,
   size_t *dim,
   size_t *stride
@@ -56,7 +58,15 @@ static inline __attribute__((always_inline)) void *array_new(
   return p;
 }
 
-static inline __attribute__((always_inline)) void *array_new0(void) {
+static inline __attribute__((always_inline)) void array_free(
+  struct array *self
+) {
+  free(self);
+}
+
+// following are more optimized constructors for when number of dimensions
+// is known but strides are not known and must be calculated from dimensions
+static inline __attribute__((always_inline)) struct array *array_new0(void) {
   struct array *p = aligned_alloc(
     ALIGN,
     (
@@ -77,7 +87,21 @@ static inline __attribute__((always_inline)) void *array_new0(void) {
   return p;
 }
 
-static inline __attribute__((always_inline)) void *array_new1(
+static inline __attribute__((always_inline)) struct array *array_new0_init(
+  const void *src
+) {
+  struct array *p = array_new0();
+  memcpy(p->data, src, p->stride[0]);
+  return p;
+}
+
+static inline __attribute__((always_inline)) struct array *array_new0_zero(void) {
+  struct array *p = array_new0();
+  memset(p->data, 0, p->stride[0]);
+  return p;
+}
+
+static inline __attribute__((always_inline)) struct array *array_new1(
   size_t dim0
 ) {
   struct array *p = aligned_alloc(
@@ -102,7 +126,24 @@ static inline __attribute__((always_inline)) void *array_new1(
   return p;
 }
 
-static inline __attribute__((always_inline)) void *array_new2(
+static inline __attribute__((always_inline)) struct array *array_new1_init(
+  size_t dim0,
+  const void *src
+) {
+  struct array *p = array_new1(dim0);
+  memcpy(p->data, src, p->stride[0]);
+  return p;
+}
+
+static inline __attribute__((always_inline)) struct array *array_new1_zero(
+  size_t dim0
+) {
+  struct array *p = array_new1(dim0);
+  memset(p->data, 0, p->stride[0]);
+  return p;
+}
+static inline __attribute__((always_inline)) struct array *array_new2(
   size_t dim0,
   size_t dim1
 ) {
@@ -130,7 +171,26 @@ static inline __attribute__((always_inline)) void *array_new2(
   return p;
 }
 
-static inline __attribute__((always_inline)) void *array_new3(
+static inline __attribute__((always_inline)) struct array *array_new2_init(
+  size_t dim0,
+  size_t dim1,
+  const void *src
+) {
+  struct array *p = array_new2(dim0, dim1);
+  memcpy(p->data, src, p->stride[0]);
+  return p;
+}
+
+static inline __attribute__((always_inline)) struct array *array_new2_zero(
+  size_t dim0,
+  size_t dim1
+) {
+  struct array *p = array_new2(dim0, dim1);
+  memset(p->data, 0, p->stride[0]);
+  return p;
+}
+static inline __attribute__((always_inline)) struct array *array_new3(
   size_t dim0,
   size_t dim1,
   size_t dim2
@@ -161,7 +221,28 @@ static inline __attribute__((always_inline)) void *array_new3(
   return p;
 }
 
-static inline __attribute__((always_inline)) void *array_new4(
+static inline __attribute__((always_inline)) struct array *array_new3_init(
+  size_t dim0,
+  size_t dim1,
+  size_t dim2,
+  const void *src
+) {
+  struct array *p = array_new3(dim0, dim1, dim2);
+  memcpy(p->data, src, p->stride[0]);
+  return p;
+}
+
+static inline __attribute__((always_inline)) struct array *array_new3_zero(
+  size_t dim0,
+  size_t dim1,
+  size_t dim2
+) {
+  struct array *p = array_new3(dim0, dim1, dim2);
+  memset(p->data, 0, p->stride[0]);
+  return p;
+}
+static inline __attribute__((always_inline)) struct array *array_new4(
   size_t dim0,
   size_t dim1,
   size_t dim2,
@@ -195,10 +276,27 @@ static inline __attribute__((always_inline)) void *array_new4(
   return p;
 }
 
-static inline __attribute__((always_inline)) void array_free(
-  struct array *self
+static inline __attribute__((always_inline)) struct array *array_new4_init(
+  size_t dim0,
+  size_t dim1,
+  size_t dim2,
+  size_t dim3,
+  const void *src
 ) {
-  free(self);
+  struct array *p = array_new4(dim0, dim1, dim2, dim3);
+  memcpy(p->data, src, p->stride[0]);
+  return p;
+}
+
+static inline __attribute__((always_inline)) struct array *array_new4_zero(
+  size_t dim0,
+  size_t dim1,
+  size_t dim2,
+  size_t dim3
+) {
+  struct array *p = array_new4(dim0, dim1, dim2, dim3);
+  memset(p->data, 0, p->stride[0]);
+  return p;
 }
 
 static inline __attribute__((always_inline)) void *array_index0(
@@ -324,38 +422,38 @@ static inline __attribute__((always_inline)) void array_set0(
 
 static inline __attribute__((always_inline)) void array_set1(
   struct array *self,
-  const void *src,
-  size_t i0
+  size_t i0,
+  const void *src
 ) {
   memcpy(array_index1(self, i0), src, self->stride[1]);
 }
 
 static inline __attribute__((always_inline)) void array_set2(
   struct array *self,
-  const void *src,
   size_t i0,
-  size_t i1
+  size_t i1,
+  const void *src
 ) {
   memcpy(array_index2(self, i0, i1), src, self->stride[2]);
 }
 
 static inline __attribute__((always_inline)) void array_set3(
   struct array *self,
-  const void *src,
   size_t i0,
   size_t i1,
-  size_t i2
+  size_t i2,
+  const void *src
 ) {
   memcpy(array_index3(self, i0, i1, i2), src, self->stride[3]);
 }
 
 static inline __attribute__((always_inline)) void array_set4(
   struct array *self,
-  const void *src,
   size_t i0,
   size_t i1,
   size_t i2,
-  size_t i3
+  size_t i3,
+  const void *src
 ) {
   memcpy(array_index4(self, i0, i1, i2, i3), src, self->stride[4]);
 }
index 00d8674..3521303 100644 (file)
--- a/render.c
+++ b/render.c
@@ -86,7 +86,7 @@ void mul_mat33_mat34(struct array *A, struct array *B, struct array *C) {
         array_get2(B, &b, k, j);
         c += a * b;
       }
-      array_set2(C, &c, i, j);
+      array_set2(C, i, j, &c);
     }
 }
 void mul_mat34_mat44(struct array *A, struct array *B, struct array *C) {
@@ -99,7 +99,7 @@ void mul_mat34_mat44(struct array *A, struct array *B, struct array *C) {
         array_get2(B, &b, k, j);
         c += a * b;
       }
-      array_set2(C, &c, i, j);
+      array_set2(C, i, j, &c);
     }
 }
 void mul_mat44_mat44(struct array *A, struct array *B, struct array *C) {
@@ -112,7 +112,7 @@ void mul_mat44_mat44(struct array *A, struct array *B, struct array *C) {
         array_get2(B, &b, k, j);
         c += a * b;
       }
-      array_set2(C, &c, i, j);
+      array_set2(C, i, j, &c);
     }
 }
 void mul_mat34_vec4(struct array *A, struct array *B, struct array *C) {
@@ -124,13 +124,12 @@ void mul_mat34_vec4(struct array *A, struct array *B, struct array *C) {
       array_get1(B, &b, j);
       c += a * b;
     }
-    array_set1(C, &c, i);
+    array_set1(C, i, &c);
   }
 }
 
 void rotate(const float (*v)[4], struct array *transform) {
-  struct array *t0 = array_new3(4, 4, sizeof(float));
-  array_set0(t0, v);
+  struct array *t0 = array_new3_init(4, 4, sizeof(float), v);
   struct array *t1 = array_new3(4, 4, sizeof(float));
   mul_mat44_mat44(t0, transform, t1);
   array_set0(transform, array_index0(t1));
@@ -173,58 +172,62 @@ int main(void) {
   }
 
   // device
-  struct array *device_transform = array_new3(3, 3, sizeof(float));
-  {
-    float v[3][3] = {
+  struct array *device_transform = array_new3_init(
+    3,
+    3,
+    sizeof(float),
+    (float[3][3]){
       {WINDOW_WIDTH, 0.f, .5f * WINDOW_WIDTH},
       {0.f, WINDOW_WIDTH, .5f * WINDOW_HEIGHT},
       {0.f, 0.f, 1.f},
-    };
-    array_set0(device_transform, v);
-  }
+    }
+  );
   printf("device_transform\n");
   print_mat330(device_transform);
   printf("\n");
 
   // perspective
-  struct array *perspective_transform = array_new3(3, 4, sizeof(float));
-  {
-    float v[3][4] = {
+  struct array *perspective_transform = array_new3_init(
+    3,
+    4,
+    sizeof(float),
+    (float[3][4]){
       {1.f, 0.f, 0.f, 0.f},
       {0.f, 0.f, 1.f, 0.f},
       {0.f, 1.f, 0.f, 0.f},
-    };
-    array_set0(perspective_transform, v);
-  }
+    }
+  );
   printf("perspective_transform\n");
   print_mat340(perspective_transform);
   printf("\n");
 
   // camera
-  struct array *camera_rotate = array_new3(4, 4, sizeof(float));
-  {
-    float v[4][4] = {
+  struct array *camera_rotate = array_new3_init(
+    4,
+    4,
+    sizeof(float),
+    (float[4][4]){
       {1.f, 0.f, 0.f, 0.f},
       {0.f, 1.f, 0.f, 0.f},
       {0.f, 0.f, 1.f, 0.f},
       {0.f, 0.f, 0.f, 1.f}
-    };
-    array_set0(camera_rotate, v);
-  }
+    }
+  );
   printf("camera_rotate\n");
   print_mat440(camera_rotate);
   printf("\n");
 
-  struct array *camera_translate = array_new3(4, 4, sizeof(float));
-  {
-    float v[4][4] = {
+  struct array *camera_translate = array_new3_init(
+    4,
+    4,
+    sizeof(float),
+    (float[4][4]){
       {1.f, 0.f, 0.f, 0.f},
       {0.f, 1.f, 0.f, 10.f},
       {0.f, 0.f, 1.f, 0.f},
       {0.f, 0.f, 0.f, 1.f}
-    };
-    array_set0(camera_translate, v);
-  }
+    }
+  );
   printf("camera_translate\n");
   print_mat440(camera_translate);
   printf("\n");
@@ -235,7 +238,7 @@ int main(void) {
     for (int j = 0; j < 2; ++j)
       for (int k = 0; k < 2; ++k) {
         float v[4] = {i * 2 - 1, j * 2 - 1, k * 2 - 1, 1.f};
-        array_set1(model_vertices, v, i * 4 + j * 2 + k);
+        array_set1(model_vertices, i * 4 + j * 2 + k, v);
       }
   printf("model_vertices\n");
   for (int i = 0; i < 8; ++i) {
@@ -276,30 +279,32 @@ int main(void) {
     //{7, 3}, // 1, 1, 1 -> 0, 1, 1
   };
 
-  struct array *model_rotate = array_new3(4, 4, sizeof(float));
-  {
-    float v[4][4] = {
+  struct array *model_rotate = array_new3_init(
+    4,
+    4,
+    sizeof(float),
+    (float[4][4]){
       {1.f, 0.f, 0.f, 0.f},
       {0.f, 1.f, 0.f, 0.f},
       {0.f, 0.f, 1.f, 0.f},
       {0.f, 0.f, 0.f, 1.f}
-    };
-    array_set0(model_rotate, v);
-  }
+    }
+  );
   printf("model_rotate\n");
   print_mat440(model_rotate);
   printf("\n");
 
-  struct array *model_translate = array_new3(4, 4, sizeof(float));
-  {
-    float v[4][4] = {
+  struct array *model_translate = array_new3_init(
+    4,
+    4,
+    sizeof(float),
+    (float[4][4]){
       {1.f, 0.f, 0.f, 0.f},
       {0.f, 1.f, 0.f, 0.f},
       {0.f, 0.f, 1.f, 0.f},
       {0.f, 0.f, 0.f, 1.f}
-    };
-    array_set0(model_translate, v);
-  }
+    }
+  );
   printf("model_translate\n");
   print_mat440(model_translate);
   printf("\n");
@@ -413,7 +418,7 @@ int main(void) {
           array_get2(model_vertices, &b, i, k);
           c += a * b;
         }
-        array_set2(p, &c, i, j);
+        array_set2(p, i, j, &c);
       }
 
     // unproject
@@ -423,7 +428,7 @@ int main(void) {
       if (v[2] >= EPSILON) {
         v[0] /= v[2];
         v[1] /= v[2];
-        array_set1(p, v, i);
+        array_set1(p, i, v);
       }
     }