Added kernel filter to r0. Wrote a lot of gl matrix method generation

This commit is contained in:
Андреев Григорий 2025-07-21 11:07:36 +03:00
parent 80c24fa4cf
commit 9a870d7101
11 changed files with 1022 additions and 96 deletions

3
.gitignore vendored
View File

@ -2,4 +2,5 @@
cmake-build-debug/
.idea/
vgcore.*
gen/
gen/
*.pdf

View File

@ -0,0 +1,34 @@
#ifndef PROTOTYPE1_SRC_L1_CORE_VECU8_PRINT_H
#define PROTOTYPE1_SRC_L1_CORE_VECU8_PRINT_H
#include <stdarg.h>
#include "./VecSpan_int_primitives.h"
VecU8 VecU8_format(const char *fmt, ...)
{
if (!fmt)
abortf("NULL passed as format\n");
/* first pass: figure out required length */
va_list ap;
va_start(ap, fmt);
va_list ap_copy;
va_copy(ap_copy, ap);
/* bytes *without* NUL */
const int needed = vsnprintf(NULL, 0, fmt, ap);
va_end(ap);
if (needed < 0)
abortf("Formatting error\n");
const size_t len = (size_t)needed;
/* allocate buffer (+1 so vsnprintf can add its NUL) */
U8 *buf = safe_malloc(len + 1);
/* second pass: actually format */
vsnprintf((char *)buf, len + 1, fmt, ap_copy);
va_end(ap_copy);
return (VecU8){ .buf = buf, .len = len, .capacity = len + 1 };
}
#endif

View File

@ -1,6 +1,7 @@
#include <stdio.h>
#include "system/fileio.h"
#include "core/VecU8_format.h"
NODISCARD VecU8 begin_header(ConstSpanU8 guard) {
VecU8 res = VecU8_new();
@ -8,7 +9,8 @@ NODISCARD VecU8 begin_header(ConstSpanU8 guard) {
VecU8_append_span(&res, guard);
VecU8_append_span(&res, cstr("\n#define "));
VecU8_append_span(&res, guard);
VecU8_append_span(&res, cstr("\n/* Automatically generated file. Do not edit it. */\n"));
VecU8_append_span(&res, cstr("\n/* Automatically generated file. Do not edit it. */\n\n"
"#include \"../src/l1/core/int_primitives.h\"\n\n"));
return res;
}
@ -18,9 +20,17 @@ void finish_header(VecU8 text_before_endif) {
VecU8_drop(text_before_endif);
}
void string_append_spaces(VecU8* str, int sc) {
for (int i = 0; i < sc; i++)
VecU8_append(str, ' ');
#define SPACE4 " "
void string_append_vec_field_name(VecU8* str, int ci) {
assert(0 <= ci && ci < 4);
VecU8_append(str, ci == 3 ? 'w' : 'x' + ci);
}
void string_append_xvecy(VecU8* str, ConstSpanU8 xvec, int cc) {
VecU8_append_span(str, xvec);
VecU8_append(str, '0' + cc);
}
NODISCARD VecU8 generate_xvecy_struct_definition(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
@ -28,46 +38,532 @@ NODISCARD VecU8 generate_xvecy_struct_definition(ConstSpanU8 xvec, ConstSpanU8 m
VecU8 res = VecU8_new();
VecU8_append_span(&res, cstr("typedef struct {\n"));
string_append_spaces(&res, 4);
VecU8_append_span(&res, member);
VecU8_append_span(&res, cstr(" x;\n"));
string_append_spaces(&res, 4);
VecU8_append_span(&res, member);
VecU8_append_span(&res, cstr(" y;\n"));
if (cc >= 3) {
string_append_spaces(&res, 4);
for (int ci = 0; ci < cc; ci++) {
VecU8_append_span(&res, cstr(SPACE4));
VecU8_append_span(&res, member);
VecU8_append_span(&res, cstr(" z;\n"));
}
if (cc >= 4) {
string_append_spaces(&res, 4);
VecU8_append_span(&res, member);
VecU8_append_span(&res, cstr(" w;\n"));
VecU8_append(&res, ' ');
string_append_vec_field_name(&res, ci);
VecU8_append_span(&res, cstr(";\n"));
}
VecU8_append_span(&res, cstr("} "));
VecU8_append_span(&res, xvec);
VecU8_append(&res, '0' + cc);
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr(";\n\n"));
return res;
}
NODISCARD VecU8 generate_xvec234_struct_definition(ConstSpanU8 xvec, ConstSpanU8 member) {
// todo: replace all these number operations with function forms
NODISCARD VecU8 generate_xvecy_method_add_xvecy(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
VecU8 res = VecU8_new();
VecU8_append_vec(&res, generate_xvecy_struct_definition(xvec, member, 2));
VecU8_append_vec(&res, generate_xvecy_struct_definition(xvec, member, 3));
VecU8_append_vec(&res, generate_xvecy_struct_definition(xvec, member, 4));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr(" "));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr("_add_"));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr("("));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr(" A, "));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr("){ "));
for (int ci = 0; ci < cc; ci++) {
if (ci)
VecU8_append_span(&res, cstr(", "));
VecU8_append_span(&res, cstr("A."));
string_append_vec_field_name(&res, ci);
VecU8_append_span(&res, cstr(" + B."));
string_append_vec_field_name(&res, ci);
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
return res;
}
NODISCARD VecU8 generate_xvecy_method_minus_xvecy(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
VecU8 res = VecU8_new();
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr(" "));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr("_minus_"));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr("("));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr(" A, "));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr("){ "));
for (int ci = 0; ci < cc; ci++) {
if (ci)
VecU8_append_span(&res, cstr(", "));
VecU8_append_span(&res, cstr("A."));
string_append_vec_field_name(&res, ci);
VecU8_append_span(&res, cstr(" - B."));
string_append_vec_field_name(&res, ci);
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
return res;
}
NODISCARD VecU8 generate_xvecy_method_minus(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
VecU8 res = VecU8_new();
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr(" "));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr("_minus("));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr(" A) {\n" SPACE4 "return("));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr("){ "));
for (int ci = 0; ci < cc; ci++) {
if (ci)
VecU8_append_span(&res, cstr(", "));
VecU8_append_span(&res, cstr("-A."));
string_append_vec_field_name(&res, ci);
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
return res;
}
NODISCARD VecU8 generate_xvecy_method_mul_scal(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
VecU8 res = VecU8_new();
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr(" "));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr("_mul_scal("));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr(" A, "));
VecU8_append_span(&res, member);
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr("){ "));
for (int ci = 0; ci < cc; ci++) {
if (ci)
VecU8_append_span(&res, cstr(", "));
VecU8_append_span(&res, cstr("A."));
string_append_vec_field_name(&res, ci);
VecU8_append_span(&res, cstr(" * B"));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
return res;
}
NODISCARD VecU8 generate_xvecy_method_div_by_scal(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
VecU8 res = VecU8_new();
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr(" "));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr("_div_by_scal("));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr(" A, "));
VecU8_append_span(&res, member);
VecU8_append_span(&res, cstr(" B){\n" SPACE4 "return "));
string_append_xvecy(&res, xvec, cc);
VecU8_append_span(&res, cstr("_mul_scal(A, 1/B);\n}\n\n"));
return res;
}
void string_append_xmatnm(VecU8* str, ConstSpanU8 xmat, int cols, int rows) {
VecU8_append_span(str, xmat);
VecU8_append(str, '0' + cols);
if (rows != cols) {
VecU8_append(str, 'x');
VecU8_append(str, '0' + rows);
}
}
/* With columns padded to 16 bytes (for std140, std140 is our everything) */
NODISCARD VecU8 generate_xmatnm_structure_definition(ConstSpanU8 xmat, ConstSpanU8 xvec, int cols, int rows, int sizeof_member) {
int sv = (rows * sizeof_member) % 16;
VecU8 res = VecU8_from_cstr("typedef struct {\n");
for (int x = 0; x < cols; x++) {
VecU8_append_span(&res, cstr(SPACE4));
string_append_xvecy(&res, xvec, rows);
VecU8_append_span(&res, cstr(" "));
string_append_vec_field_name(&res, x);
VecU8_append_span(&res, cstr(";\n"));
if (sv) {
VecU8_append_vec(&res, VecU8_format(SPACE4 "char _padding_%d[%d];\n", x, 16 - sv));
}
}
VecU8_append_span(&res, cstr("} "));
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr(";\n\n"));
return res;
}
void string_append_mat_col_definition(VecU8* str, int ci) {
VecU8_append(str, '.');
string_append_vec_field_name(str, ci);
VecU8_append_span(str, cstr(" = "));
}
void string_append_mat_el_access(VecU8* str, int x, int y) {
VecU8_append(str, '.');
string_append_vec_field_name(str, x);
VecU8_append(str, '.');
string_append_vec_field_name(str, y);
}
NODISCARD VecU8 generate_xmatnm_method_new(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
VecU8 res = VecU8_new();
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append(&res, ' ');
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr("_new("));
for (int y = 0; y < rows; y++) {
for (int x = 0; x < cols; x++) {
if (x > 0 || y > 0)
VecU8_append_span(&res, cstr(", "));
VecU8_append_span(&res, member);
VecU8_append(&res, ' ');
string_append_vec_field_name(&res, x);
string_append_vec_field_name(&res, y);
}
}
VecU8_append_span(&res, cstr(") {\n" SPACE4 "return ("));
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr("){ "));
for (int x = 0; x < cols; x++) {
if (x)
VecU8_append_span(&res, cstr(", "));
string_append_mat_col_definition(&res, x);
VecU8_append_span(&res, cstr("{ "));
for (int y = 0; y < rows; y++) {
if (y)
VecU8_append_span(&res, cstr(", "));
string_append_vec_field_name(&res, x);
string_append_vec_field_name(&res, y);
}
VecU8_append_span(&res, cstr(" }"));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
return res;
}
NODISCARD VecU8 generate_square_xmatnn_E_definition(ConstSpanU8 xmat, int n) {
VecU8 res = VecU8_from_cstr("const ");
string_append_xmatnm(&res, xmat, n, n);
VecU8_append(&res, ' ');
string_append_xmatnm(&res, xmat, n, n);
VecU8_append_span(&res, cstr("_E = { "));
for (int x = 0; x < n; x++) {
if (x)
VecU8_append_span(&res, cstr(", "));
string_append_mat_col_definition(&res, x);
VecU8_append_span(&res, cstr("{ "));
for (int y = 0; y < n; y++) {
if (y)
VecU8_append_span(&res, cstr(", "));
VecU8_append(&res, '0' + (x == y));
}
VecU8_append_span(&res, cstr(" }"));
}
VecU8_append_span(&res, cstr(" };\n\n"));
return res;
}
NODISCARD VecU8 generate_xmatnm_method_add_xmatnm(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
VecU8 res = VecU8_new();
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append(&res, ' ');
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr("_add_"));
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr("("));
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr(" A, "));
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr("){ "));
for (int x = 0; x < cols; x++) {
if (x)
VecU8_append_span(&res, cstr(", "));
string_append_mat_col_definition(&res, x);
string_append_xvecy(&res, xvec, rows);
VecU8_append_span(&res, cstr("_add_"));
string_append_xvecy(&res, xvec, rows);
VecU8_append_span(&res, cstr("(A."));
string_append_vec_field_name(&res, x);
VecU8_append_span(&res, cstr(", B."));
string_append_vec_field_name(&res, x);
VecU8_append_span(&res, cstr(")"));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
return res;
}
NODISCARD VecU8 generate_xmatnm_method_minus_xmatnm(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
VecU8 res = VecU8_new();
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append(&res, ' ');
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr("_minus_"));
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr("("));
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr(" A, "));
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr("){ "));
for (int x = 0; x < cols; x++) {
if (x)
VecU8_append_span(&res, cstr(", "));
string_append_mat_col_definition(&res, x);
string_append_xvecy(&res, xvec, rows);
VecU8_append_span(&res, cstr("_minus_"));
string_append_xvecy(&res, xvec, rows);
VecU8_append_span(&res, cstr("(A."));
string_append_vec_field_name(&res, x);
VecU8_append_span(&res, cstr(", B."));
string_append_vec_field_name(&res, x);
VecU8_append_span(&res, cstr(")"));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
return res;
}
NODISCARD VecU8 generate_xmatnm_method_minus(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
VecU8 res = VecU8_new();
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append(&res, ' ');
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr("_minus("));
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr(" A) {\n" SPACE4 "return ("));
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr("){ "));
for (int x = 0; x < cols; x++) {
if (x)
VecU8_append_span(&res, cstr(", "));
string_append_mat_col_definition(&res, x);
string_append_xvecy(&res, xvec, rows);
VecU8_append_span(&res, cstr("_minus(A."));
string_append_vec_field_name(&res, x);
VecU8_append_span(&res, cstr(")"));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
return res;
}
NODISCARD VecU8 generate_xmatnm_method_mul_scal(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
VecU8 res = VecU8_new();
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append(&res, ' ');
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr("_mul_scal("));
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr(" A, "));
VecU8_append_span(&res, member);
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr("){ "));
for (int x = 0; x < cols; x++) {
if (x)
VecU8_append_span(&res, cstr(", "));
string_append_mat_col_definition(&res, x);
string_append_xvecy(&res, xvec, rows);
VecU8_append_span(&res, cstr("_mul_scal(A."));
string_append_vec_field_name(&res, x);
VecU8_append_span(&res, cstr(", B)"));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
return res;
}
NODISCARD VecU8 generate_xmatnm_method_div_by_scal(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
VecU8 res = VecU8_new();
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append(&res, ' ');
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr("_div_by_scal("));
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr(" A, "));
VecU8_append_span(&res, member);
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return "));
string_append_xmatnm(&res, xmat, cols, rows);
VecU8_append_span(&res, cstr("_mul_scal(A, 1/B);\n}\n\n"));
return res;
}
NODISCARD VecU8 generate_xvecn_method_dot_xvecn(ConstSpanU8 xvec, ConstSpanU8 member, int n) {
VecU8 res = VecU8_from_span(member);
VecU8_append(&res, ' ');
string_append_xvecy(&res, xvec, n);
VecU8_append_span(&res, cstr("_dot_"));
string_append_xvecy(&res, xvec, n);
VecU8_append(&res, '(');
string_append_xvecy(&res, xvec, n);
VecU8_append_span(&res, cstr(" A, "));
string_append_xvecy(&res, xvec, n);
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return "));
for (int i = 0; i < n; i++) {
if (i)
VecU8_append_span(&res, cstr(" + "));
VecU8_append_span(&res, cstr("A."));
string_append_vec_field_name(&res, i);
VecU8_append_span(&res, cstr(" * B."));
string_append_vec_field_name(&res, i);
}
VecU8_append_span(&res, cstr(";\n}\n\n"));
return res;
}
NODISCARD VecU8 generate_xmatnm_method_mul_xvecn(ConstSpanU8 xmat, ConstSpanU8 xvec, int n, int m) {
VecU8 res = VecU8_new();
string_append_xvecy(&res, xvec, m);
VecU8_append(&res, ' ');
string_append_xmatnm(&res, xmat, n, m);
VecU8_append_span(&res, cstr("_mul_"));
string_append_xvecy(&res, xvec, n);
VecU8_append_span(&res, cstr("("));
string_append_xmatnm(&res, xmat, n, m);
VecU8_append_span(&res, cstr(" A, "));
string_append_xvecy(&res, xvec, n);
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
string_append_xvecy(&res, xvec, m);
VecU8_append_span(&res, cstr("){"));
for (int ci = 0; ci < m; ci++) {
if (ci)
VecU8_append(&res, ',');
VecU8_append_span(&res, cstr("\n" SPACE4 SPACE4));
for (int x = 0; x < n; x++) {
if (x)
VecU8_append_span(&res, cstr(" + "));
VecU8_append_span(&res, cstr("A"));
string_append_mat_el_access(&res, x, ci);
VecU8_append_span(&res, cstr(" * B."));
string_append_vec_field_name(&res, x);
}
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
return res;
}
NODISCARD VecU8 generate_xmatnm_method_mul_xmatkn(ConstSpanU8 xmat, int n, int m, int k) {
VecU8 res = VecU8_new();
string_append_xmatnm(&res, xmat, k, m);
VecU8_append(&res, ' ');
string_append_xmatnm(&res, xmat, n, m);
VecU8_append_span(&res, cstr("_mul_"));
string_append_xmatnm(&res, xmat, k, n);
VecU8_append_span(&res, cstr("("));
string_append_xmatnm(&res, xmat, n, m);
VecU8_append_span(&res, cstr(" A, "));
string_append_xmatnm(&res, xmat, k, n);
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
string_append_xmatnm(&res, xmat, k, m);
VecU8_append_span(&res, cstr("){"));
for (int x = 0; x < k; x++) {
if (x)
VecU8_append_span(&res, cstr(","));
VecU8_append_span(&res, cstr("\n" SPACE4 SPACE4));
string_append_mat_col_definition(&res, x);
VecU8_append_span(&res, cstr("{ "));
for (int y = 0; y < m; y++) {
if (y)
VecU8_append_span(&res, cstr(", "));
for (int z = 0; z < n; z++) {
if (z)
VecU8_append_span(&res, cstr(" + "));
VecU8_append_span(&res, cstr("A"));
string_append_mat_el_access(&res, z, y);
VecU8_append_span(&res, cstr(" * B"));
string_append_mat_el_access(&res, x, z);
}
}
VecU8_append_span(&res, cstr(" }"));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
return res;
}
VecU8 generate_xmatnm_method_transpose(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int n, int m) {
VecU8 res = VecU8_new();
string_append_xmatnm(&res, xmat, m, n);
VecU8_append(&res, ' ');
string_append_xmatnm(&res, xmat, n, m);
VecU8_append_span(&res, cstr("_transpose("));
string_append_xmatnm(&res, xmat, n, m);
VecU8_append_span(&res, cstr(" A) {\n" SPACE4 "return ("));
string_append_xmatnm(&res, xmat, m, n);
VecU8_append_span(&res, cstr("){ "));
for (int bx = 0; bx < m; bx++) {
if (bx)
VecU8_append_span(&res, cstr(", "));
string_append_mat_col_definition(&res, bx);
VecU8_append_span(&res, cstr("{ "));
for (int by = 0; by < n; by++) {
if (by)
VecU8_append_span(&res, cstr(", "));
VecU8_append_span(&res, cstr("A"));
string_append_mat_el_access(&res, by, bx);
}
VecU8_append_span(&res, cstr(" }"));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
return res;
}
NODISCARD VecU8 generate_xvec234_structs_and_methods(ConstSpanU8 xvec, ConstSpanU8 member) {
VecU8 res = VecU8_new();
for (int cc = 2; cc <= 4; cc++) {
VecU8_append_vec(&res, generate_xvecy_struct_definition(xvec, member, cc));
VecU8_append_vec(&res, generate_xvecy_method_add_xvecy(xvec, member, cc));
VecU8_append_vec(&res, generate_xvecy_method_minus_xvecy(xvec, member, cc));
VecU8_append_vec(&res, generate_xvecy_method_minus(xvec, member, cc));
VecU8_append_vec(&res, generate_xvecy_method_mul_scal(xvec, member, cc));
VecU8_append_vec(&res, generate_xvecy_method_div_by_scal(xvec, member, cc));
}
return res;
}
NODISCARD VecU8 generate_xmat234x234_structs_and_methods(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int sizeof_member) {
VecU8 res = VecU8_new();
for (int cols = 2; cols <= 4; cols++) {
for (int rows = 2; rows <= 4; rows++) {
VecU8_append_vec(&res, generate_xmatnm_structure_definition(xmat, xvec, cols, rows, sizeof_member));
}
}
for (int cols = 2; cols <= 4; cols++) {
for (int rows = 2; rows <= 4; rows++) {
VecU8_append_vec(&res, generate_xmatnm_method_new(xmat, xvec, member, cols, rows));
VecU8_append_vec(&res, generate_xmatnm_method_add_xmatnm(xmat, xvec, member, cols, rows));
VecU8_append_vec(&res, generate_xmatnm_method_minus_xmatnm(xmat, xvec, member, cols, rows));
VecU8_append_vec(&res, generate_xmatnm_method_minus(xmat, xvec, member, cols, rows));
VecU8_append_vec(&res, generate_xmatnm_method_mul_scal(xmat, xvec, member, cols, rows));
VecU8_append_vec(&res, generate_xmatnm_method_div_by_scal(xmat, xvec, member, cols, rows));
VecU8_append_vec(&res, generate_xmatnm_method_transpose(xmat, xvec, member, cols, rows));
}
}
for (int n = 2; n <= 4; n++) {
VecU8_append_vec(&res, generate_square_xmatnn_E_definition(xmat, n));
}
for (int n = 2; n <= 4; n++) {
for (int m = 2; m <= 4; m++) {
VecU8_append_vec(&res, generate_xmatnm_method_mul_xvecn(xmat, xvec, n, m));
}
}
for (int n = 2; n <= 4; n++) {
for (int m = 2; m <= 4; m++) {
for (int k = 2; k <= 4; k++) {
VecU8_append_vec(&res, generate_xmatnm_method_mul_xmatkn(xmat, n, m, k));
}
}
}
return res;
}
void generate_geometry_header() {
VecU8 res = begin_header(cstr("PROTOTYPE1_GEN_GEOM"));
VecU8_append_vec(&res, generate_xvec234_struct_definition(cstr("ivec"), cstr("int32_t")));
VecU8_append_vec(&res, generate_xvec234_struct_definition(cstr("uvec"), cstr("uint32_t")));
VecU8_append_vec(&res, generate_xvec234_struct_definition(cstr("vec"), cstr("float")));
VecU8_append_vec(&res, generate_xvec234_struct_definition(cstr("dvec"), cstr("double")));
VecU8_append_vec(&res, generate_xvec234_structs_and_methods(cstr("ivec"), cstr("S32")));
VecU8_append_vec(&res, generate_xvec234_structs_and_methods(cstr("vec"), cstr("float")));
VecU8_append_vec(&res, generate_xvec234_structs_and_methods(cstr("dvec"), cstr("double")));
VecU8_append_vec(&res, generate_xmat234x234_structs_and_methods(cstr("mat"), cstr("vec"), cstr("float"), sizeof(float)));
VecU8_append_vec(&res, generate_xmat234x234_structs_and_methods(cstr("dmat"), cstr("dvec"), cstr("double"), sizeof(double)));
finish_header(res);
}

View File

@ -0,0 +1,8 @@
#ifndef PROTOTYPE1_SRC_L2_MARGARET_GRAPHICS_GEOM_H
#define PROTOTYPE1_SRC_L2_MARGARET_GRAPHICS_GEOM_H
#include "../../../gen/geom.h"
#endif

View File

@ -736,6 +736,7 @@ VkFence margaret_create_fence(VkDevice device, bool create_signaled) {
return res;
}
//todo: strip synchronization lines out of here, pls PLS DO IT ADGASDHH HDJHFHFDKKF DFKDKDK THIS IS SO STUPID
typedef struct {
VkSwapchainKHR swapchain;
VecVkImageView image_views;
@ -744,6 +745,7 @@ typedef struct {
VkSemaphore in_frame_transfer_complete;
VkSemaphore image_available_semaphore;
VkSemaphore rendered_to_IT1_semaphore;
VkSemaphore render_finished_semaphore;
VkFence in_flight_fence;
} MargaretSwapchainBundle;
@ -759,6 +761,7 @@ MargaretSwapchainBundle MargaretSwapchainBundle_new(
.framebuffers = framebuffers, .extent = swapchain_details.image_extent,
.in_frame_transfer_complete = margaret_create_semaphore(device),
.image_available_semaphore = margaret_create_semaphore(device),
.rendered_to_IT1_semaphore = margaret_create_semaphore(device),
.render_finished_semaphore = margaret_create_semaphore(device),
.in_flight_fence = margaret_create_fence(device, true),
};
@ -773,6 +776,7 @@ VkSwapchainKHR MargaretSwapchainBundle_pop_swapchain_drop_rest(VkDevice device,
}
vkDestroyFence(device, swfb.in_flight_fence, NULL);
vkDestroySemaphore(device, swfb.render_finished_semaphore, NULL);
vkDestroySemaphore(device, swfb.rendered_to_IT1_semaphore, NULL);
vkDestroySemaphore(device, swfb.image_available_semaphore, NULL);
vkDestroySemaphore(device, swfb.in_frame_transfer_complete, NULL);
// Old swapchain bundle is 83% dropped
@ -1058,6 +1062,12 @@ MargaretImageInMemoryInfo margaret_prep_image_mem_info_of_zbuffer(uint32_t max_w
.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT };
}
/* Used both for sampling and as a color attachment */
MargaretImageInMemoryInfo margaret_prep_image_mem_info_of_colorbuffer(U32 width, U32 height, VkFormat format) {
return (MargaretImageInMemoryInfo){.width = width, .height = height, .format = format,
.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT};
}
MargaretBufferInMemoryInfo margaret_prep_buffer_mem_info_of_gpu_ubo(size_t struct_sz) {
return (MargaretBufferInMemoryInfo){ .sz = struct_sz,
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT };
@ -1345,5 +1355,17 @@ void margaret_record_buf_copying_command_buf(
abortf("vkEndCommandBuffer");
}
VkDescriptorSet margaret_allocate_descriptor_set(VkDevice device, VkDescriptorPool descriptor_pool, VkDescriptorSetLayout layout) {
VkDescriptorSetAllocateInfo alloc_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = descriptor_pool,
.descriptorSetCount = 1,
.pSetLayouts = &layout,
};
VkDescriptorSet descriptor_set;
if (vkAllocateDescriptorSets(device, &alloc_info, &descriptor_set) != VK_SUCCESS)
abortf("vkAllocateDescriptorSets");
return descriptor_set;
}
#endif

View File

@ -36,7 +36,59 @@ typedef struct {
} Scene;
// todo: generate this function in l2
VkRenderPass create_render_pass(VkDevice logical_device, VkFormat image_format) {
VkRenderPass create_render_pass_1(VkDevice logical_device, VkFormat image_format) {
// Color attachments array for our render pass
VkAttachmentDescription all_attachments[1] = { (VkAttachmentDescription){
.format = image_format,
.samples = VK_SAMPLE_COUNT_1_BIT,
.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
} };
// For our one single render subpass
VkAttachmentReference color_attachment_refs[1] = { (VkAttachmentReference){
.attachment = 0,
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
} };
VkSubpassDescription subpasses_descr[1] = { (VkSubpassDescription){
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
.colorAttachmentCount = ARRAY_SIZE(color_attachment_refs),
.pColorAttachments = color_attachment_refs,
} };
VkSubpassDependency subpass_dependencies[1] = {
// subpass_0_external
(VkSubpassDependency) {
.srcSubpass = VK_SUBPASS_EXTERNAL,
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccessMask = 0,
.dstSubpass = 0,
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
}};
VkRenderPassCreateInfo render_pass_crinfo = {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
.attachmentCount = ARRAY_SIZE(all_attachments),
.pAttachments = all_attachments,
.subpassCount = ARRAY_SIZE(subpasses_descr),
.pSubpasses = subpasses_descr,
.dependencyCount = ARRAY_SIZE(subpass_dependencies),
.pDependencies = subpass_dependencies,
};
VkRenderPass render_pass;
if (vkCreateRenderPass(logical_device, &render_pass_crinfo, NULL, &render_pass) != VK_SUCCESS)
abortf("vkCreateRenderPass");
return render_pass;
}
// todo: generate this function in l2
VkRenderPass create_render_pass_0(VkDevice logical_device, VkFormat image_format) {
// Color attachments array for our render pass
VkAttachmentDescription all_attachments[1] = { (VkAttachmentDescription){
.format = image_format,
@ -59,7 +111,6 @@ VkRenderPass create_render_pass(VkDevice logical_device, VkFormat image_format)
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
.colorAttachmentCount = ARRAY_SIZE(color_attachment_refs),
.pColorAttachments = color_attachment_refs,
} };
VkSubpassDependency subpass_dependencies[1] = {
@ -102,7 +153,150 @@ void destroy_graphics_pipeline_hands(VkDevice device, PipelineHands hands) {
}
// todo: generate this function in l2
PipelineHands create_graphics_pipeline(
PipelineHands create_graphics_pipeline_1(
VkDevice device, VkRenderPass render_pass, uint32_t subpass
) {
VecU8 vert_bin_code = read_whole_file_or_abort("test_shaders/spv/1/vert.spv");
VecU8 frag_bin_code = read_whole_file_or_abort("test_shaders/spv/1/frag.spv");
VkShaderModule vert_module = margaret_VkShaderModule_new(device, vert_bin_code);
VkShaderModule frag_module = margaret_VkShaderModule_new(device, frag_bin_code);
VecU8_drop(vert_bin_code);
VecU8_drop(frag_bin_code);
VkPipelineShaderStageCreateInfo shader_stages_crinfo[2] = {
margaret_shader_stage_vertex_crinfo(vert_module),
margaret_shader_stage_fragment_crinfo(frag_module)
};
VkPipelineVertexInputStateCreateInfo vertex_input_crinfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = 0,
.pVertexBindingDescriptions = NULL,
.vertexAttributeDescriptionCount = 0,
.pVertexAttributeDescriptions = NULL,
};
VkPipelineInputAssemblyStateCreateInfo input_assembly_crinfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
.primitiveRestartEnable = VK_FALSE,
};
VkPipelineViewportStateCreateInfo viewport_state = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
// We are using dynamic viewport and scissors, that is why we do not attach viewport/scissor values
// when creating a rendering pipeline. We will do that later
.viewportCount = 1,
.scissorCount = 1,
};
VkPipelineRasterizationStateCreateInfo rasterizer_crinfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.depthClampEnable = VK_FALSE,
.polygonMode = VK_POLYGON_MODE_FILL,
.cullMode = VK_CULL_MODE_BACK_BIT,
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
.depthBiasEnable = VK_FALSE,
.depthBiasConstantFactor = 0.0f,
.depthBiasClamp = 0.0f,
.depthBiasSlopeFactor = 0.0f,
.lineWidth = 1.0f,
};
VkPipelineMultisampleStateCreateInfo multisampling_crinfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
.sampleShadingEnable = VK_FALSE,
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
.minSampleShading = 1.0f,
.pSampleMask = NULL,
.alphaToCoverageEnable = VK_FALSE,
.alphaToOneEnable = VK_FALSE,
};
// For one framebuffer
VkPipelineColorBlendAttachmentState color_blend_attachments[1] = {(VkPipelineColorBlendAttachmentState){
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
.blendEnable = VK_FALSE,
}};
// For the entire pipeline
VkPipelineColorBlendStateCreateInfo color_blending_crinfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
.logicOpEnable = VK_FALSE,
.logicOp = VK_LOGIC_OP_COPY,
.attachmentCount = ARRAY_SIZE(color_blend_attachments),
.pAttachments = color_blend_attachments,
// Blend constants specified heres
};
VkDynamicState dynamic_states[2] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
VkPipelineDynamicStateCreateInfo dynamic_state_crinfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.dynamicStateCount = ARRAY_SIZE(dynamic_states),
.pDynamicStates = dynamic_states,
};
VkDescriptorSetLayoutBinding bindings_for_my_descr_set_layout[] = {
{
.binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
},
};
VkDescriptorSetLayoutCreateInfo descriptor_set_layout_crinfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = ARRAY_SIZE(bindings_for_my_descr_set_layout),
.pBindings = bindings_for_my_descr_set_layout,
};
VkDescriptorSetLayout my_descriptor_set_layout;
if (vkCreateDescriptorSetLayout(device, &descriptor_set_layout_crinfo, NULL, &my_descriptor_set_layout) != VK_SUCCESS)
abortf("vkCreateDescriptorSetLayout");
VkPushConstantRange used_region_sz_push_const = {
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
.offset = 0, .size = sizeof(vec2)
};
VkPipelineLayoutCreateInfo layout_crinfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = 1,
.pSetLayouts = &my_descriptor_set_layout,
.pushConstantRangeCount = 1,
.pPushConstantRanges = &used_region_sz_push_const,
};
VkPipelineLayout pipeline_layout;
if (vkCreatePipelineLayout(device, &layout_crinfo, NULL, &pipeline_layout) != VK_SUCCESS)
abortf("vkCreatePipelineLayout");
// todo: kill myself (update: still todo (update: still not done )) update: work in progress
VkGraphicsPipelineCreateInfo pipeline_crinfo = {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.stageCount = ARRAY_SIZE(shader_stages_crinfo),
.pStages = shader_stages_crinfo,
.pVertexInputState = &vertex_input_crinfo,
.pInputAssemblyState = &input_assembly_crinfo,
.pViewportState = &viewport_state,
.pRasterizationState = &rasterizer_crinfo,
.pMultisampleState = &multisampling_crinfo,
.pDepthStencilState = NULL,
.pColorBlendState = &color_blending_crinfo,
.pDynamicState = &dynamic_state_crinfo,
.layout = pipeline_layout,
.renderPass = render_pass,
.subpass = subpass,
.basePipelineHandle = VK_NULL_HANDLE,
};
VkPipeline pipeline;
if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_crinfo, NULL, &pipeline) != VK_SUCCESS)
abortf("vkCreateGraphicsPipelines");
vkDestroyShaderModule(device, frag_module, NULL);
vkDestroyShaderModule(device, vert_module, NULL);
return (PipelineHands){.pipeline_layout = pipeline_layout, .pipeline = pipeline, .descriptor_set_layout = my_descriptor_set_layout};
}
PipelineHands create_graphics_pipeline_0(
VkDevice device, VkRenderPass render_pass, uint32_t subpass
) {
VecU8 vert_bin_code = read_whole_file_or_abort("test_shaders/spv/0/vert.spv");
@ -240,7 +434,6 @@ PipelineHands create_graphics_pipeline(
VkPipelineLayout pipeline_layout;
if (vkCreatePipelineLayout(device, &layout_crinfo, NULL, &pipeline_layout) != VK_SUCCESS)
abortf("vkCreatePipelineLayout");
// todo: kill myself (update: still todo (update: still not done )) update: work in progress
VkGraphicsPipelineCreateInfo pipeline_crinfo = {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.stageCount = ARRAY_SIZE(shader_stages_crinfo),
@ -259,6 +452,8 @@ PipelineHands create_graphics_pipeline(
.basePipelineHandle = VK_NULL_HANDLE,
};
// todo: actually use this function
VkPipeline pipeline;
if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_crinfo, NULL, &pipeline) != VK_SUCCESS)
abortf("vkCreateGraphicsPipelines");
@ -268,8 +463,26 @@ PipelineHands create_graphics_pipeline(
return (PipelineHands){.pipeline_layout = pipeline_layout, .pipeline = pipeline, .descriptor_set_layout = my_descriptor_set_layout};
}
void reset_and_record_command_buffer(
VkCommandBuffer command_buffer, VkRenderPass render_pass,
VkFramebuffer create_IT1_framebuffer(VkDevice device, VkImageView IT1_view, VkRenderPass render_pass_0, VkExtent2D MAX_WIN_SIZE) {
VkImageView attachments[1] = {IT1_view};
VkFramebufferCreateInfo framebuffer_crinfo = {
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
.renderPass = render_pass_0,
.attachmentCount = ARRAY_SIZE(attachments),
.pAttachments = attachments,
.width = MAX_WIN_SIZE.width,
.height = MAX_WIN_SIZE.height,
.layers = 1
};
VkFramebuffer framebuffer;
if (vkCreateFramebuffer(device, &framebuffer_crinfo, NULL, &framebuffer) != VK_SUCCESS)
abortf("vkCreateFramebuffer");
return framebuffer;
}
void reset_and_record_command_buffer_0(
VkCommandBuffer command_buffer, VkRenderPass render_pass_0,
const PipelineHands* pipeline_and_layout,
VkFramebuffer swapchain_image_framebuffer, VkExtent2D image_extent,
const Scene* scene, VkDescriptorSet my_descriptor_set
@ -283,7 +496,7 @@ void reset_and_record_command_buffer(
VkClearValue clear_color[1] = {{.color = scene->color}};
VkRenderPassBeginInfo renderpass_begin = {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = render_pass,
.renderPass = render_pass_0,
.framebuffer = swapchain_image_framebuffer,
.renderArea.offset = (VkOffset2D){0, 0},
.renderArea.extent = image_extent,
@ -328,6 +541,63 @@ void reset_and_record_command_buffer(
abortf("vkEndCommandBuffer");
}
void reset_and_record_command_buffer_1(
VkCommandBuffer command_buffer, VkRenderPass render_pass_1,
const PipelineHands* pipeline_and_layout_1,
VkFramebuffer swapchain_image_framebuffer, VkExtent2D image_extent,
VkExtent2D max_win_size,
VkDescriptorSet descriptor_set_for_pipeline_1
) {
if (vkResetCommandBuffer(command_buffer, 0) != VK_SUCCESS)
abortf("vkResetCommandBuffer");
VkCommandBufferBeginInfo info_begin = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
if (vkBeginCommandBuffer(command_buffer, &info_begin) != VK_SUCCESS)
abortf("vkBeginCommandBuffer");
// VkClearValue clear_color[1] = {{.color = scene->color}};
VkRenderPassBeginInfo renderpass_begin = {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = render_pass_1,
.framebuffer = swapchain_image_framebuffer,
.renderArea.offset = (VkOffset2D){0, 0},
.renderArea.extent = image_extent,
.clearValueCount = 0,
.pClearValues = NULL,
};
vkCmdBeginRenderPass(command_buffer, &renderpass_begin, VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout_1->pipeline);
VkViewport viewport = {
.x = 0.0f,
.y = 0.0f,
.width = (float)(image_extent.width),
.height = (float)(image_extent.height),
.minDepth = 0.0f,
.maxDepth = 1.0f,
};
vkCmdSetViewport(command_buffer, 0, 1, &viewport);
VkRect2D scissor = {
.offset = (VkOffset2D){0, 0},
.extent = image_extent,
};
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
vkCmdBindDescriptorSets(
command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout_1->pipeline_layout, 0,
1, &descriptor_set_for_pipeline_1, 0, NULL);
vec2 region_tex_scale = {(float)image_extent.width / (float)max_win_size.width,
(float)image_extent.height / (float)max_win_size.height};
vkCmdPushConstants(command_buffer, pipeline_and_layout_1->pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(vec2), &region_tex_scale);
vkCmdDraw(command_buffer, 3, 1, 0, 0);
vkCmdEndRenderPass(command_buffer);
if (vkEndCommandBuffer(command_buffer) != VK_SUCCESS)
abortf("vkEndCommandBuffer");
}
void recreate_swapchain(
VkPhysicalDevice physical_device, VkDevice device, MargaretChosenQueueFamilies queue_fam, VkSurfaceKHR surface,
VkRenderPass render_pass, MargaretSwapchainBundle* swfb) {
@ -369,10 +639,8 @@ int main() {
ConstSpanU8 GPU = cstr("amd");
ConstSpanU8 bugged_GPU = cstr("nvidia");
bool ENABLE_VALIDATION_LAYERS = true;
// U32 MAX_WIN_WIDTH = 1900;
// U32 MAX_WIN_HEIGHT = 800;
// int MAX_FRAMES_IN_FLIGHT = 2;
U32 MAX_WIN_WIDTH = 1920;
U32 MAX_WIN_HEIGHT = 1080;
MargaretSingleWindowSetup x = MargaretSingleWindowSetup_new();
Margaret_WEP wep = Margaret_WEP_new(x.dpy, x.win);
@ -410,17 +678,20 @@ int main() {
// We hope that the image format won't be changed even when window gets resized
// VkSurfaceFormatKHR image_format = choose_surface_format_i_want(swap_chain_support).value();
VkRenderPass render_pass = create_render_pass(device, swapchain_details.surface_format.format);
PipelineHands pipeline_hands = create_graphics_pipeline(device, render_pass, 0);
VkRenderPass render_pass_0 = create_render_pass_0(device, swapchain_details.surface_format.format);
PipelineHands pipeline_hands_0 = create_graphics_pipeline_0(device, render_pass_0, 0);
MargaretSwapchainBundle swfb = MargaretSwapchainBundle_new(device, queue_fam, swapchain_details, surface, render_pass, NULL);
VkRenderPass render_pass_1 = create_render_pass_1(device, swapchain_details.surface_format.format);
PipelineHands pipeline_hands_1 = create_graphics_pipeline_1(device, render_pass_1, 0);
MargaretSwapchainBundle swfb = MargaretSwapchainBundle_new(device, queue_fam, swapchain_details, surface, render_pass_1, NULL);
// Filling scene info
const OA_Vertex obj1_vertexes[] = {
(OA_Vertex){ .pos = {-1, -1, 0}, .tex = {0, 1} },
(OA_Vertex){ .pos = {1, -1, 0}, .tex = {1, 1} },
(OA_Vertex){ .pos = {1, 1, 0}, .tex = {1, 0} },
(OA_Vertex){ .pos = {-1, 1, 0}, .tex = {0, 0} },
(OA_Vertex){ .pos = {-1, -0.5f, 0}, .tex = {0, 1} },
(OA_Vertex){ .pos = {0.3f, -0.5f, 0}, .tex = {1, 1} },
(OA_Vertex){ .pos = {-3.f, 3.f, 0}, .tex = {1, 0} },
(OA_Vertex){ .pos = {-0.5f, .4f, 0}, .tex = {0, 0} },
};
const uint32_t obj1_indices[] = { 0, 2, 1, 0, 3, 2 };
const OA_Vertex obj2_vertexes[] = {
@ -447,6 +718,11 @@ int main() {
wood_texture_data[y][col + 3] = (color8rgba){125, 20, 20, 255};
}
}
for (U32 y = 0; y < 10; y++) {
for (U32 col = 0; col < 10; col++) {
wood_texture_data[13 + y][4 + col] = (color8rgba){140, 50, 20, 255};
}
}
// We have only one staging buffer in host memory (because we don't really need more)
MargaretBufferInMemoryInfo host_mem_buffer = (MargaretBufferInMemoryInfo){ .sz =
@ -469,7 +745,8 @@ int main() {
margaret_prep_buffer_mem_info_of_gpu_ubo(sizeof(MyUbo)),
};
MargaretImageInMemoryInfo device_mem_images[] = {
margaret_prep_image_mem_info_of_gpu_texture_rgba(wood_texture_width, wood_texture_height)
margaret_prep_image_mem_info_of_gpu_texture_rgba(wood_texture_width, wood_texture_height),
margaret_prep_image_mem_info_of_colorbuffer(MAX_WIN_WIDTH, MAX_WIN_HEIGHT, swapchain_details.surface_format.format),
};
VkDeviceMemory device_mem = margaret_initialize_buffers_and_images(physical_device, device,
(SpanMargaretBufferInMemoryInfo){ .data = device_mem_buffers, .len = ARRAY_SIZE(device_mem_buffers)},
@ -481,9 +758,11 @@ int main() {
MargaretBufferInMemoryInfo device_ebo_2_buffer = device_mem_buffers[3];
MargaretBufferInMemoryInfo device_ubo_my_buffer = device_mem_buffers[4];
MargaretImageInMemoryInfo device_wood_texture = device_mem_images[0];
MargaretImageInMemoryInfo device_IT1_image = device_mem_images[1]; // todo: use it in my shenanigans
VkCommandPool command_pool = margaret_create_resettable_command_pool(device, queue_fam.for_graphics);
VkCommandBuffer rendering_command_buffer = margaret_allocate_command_buffer(device, command_pool);
VkCommandBuffer rendering_command_buffer_0 = margaret_allocate_command_buffer(device, command_pool);
VkCommandBuffer rendering_command_buffer_1 = margaret_allocate_command_buffer(device, command_pool);
VkCommandBuffer uniform_transfer_command_buffer = margaret_allocate_command_buffer(device, command_pool);
margaret_record_buf_copying_command_buf(device, uniform_transfer_command_buffer,
@ -513,6 +792,12 @@ int main() {
// My wood texture needs VkImageView
VkImageView wood_texture_view = margaret_create_view_for_image(device, &device_wood_texture, VK_IMAGE_ASPECT_COLOR_BIT);
/* Here we create an image view into a temporary IT1 texture and a framebuffer for scene rendering */
VkImageView IT1_view = margaret_create_view_for_image(device, &device_IT1_image, VK_IMAGE_ASPECT_COLOR_BIT);
// todo: I will get back here soon
VkFramebuffer IT1_framebuffer = create_IT1_framebuffer(device, IT1_view, render_pass_0,
(VkExtent2D){.width = MAX_WIN_WIDTH, .height = MAX_WIN_HEIGHT});
Scene scene;
scene.oa_objects = VecOA_ObjectOnScene_new_zeroinit(2);
*VecOA_ObjectOnScene_at(&scene.oa_objects, 0) = (OA_ObjectOnScene){
@ -523,48 +808,59 @@ int main() {
// Sampler is global for a lot of my future textures
VkSampler my_texture_sampler = margaret_create_sampler(physical_device, device);
VkDescriptorPool descriptor_pool = margaret_create_descriptor_set_pool(device, 1, 1, 2);
VkDescriptorSetAllocateInfo descriptor_sets_alloc_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = descriptor_pool,
.descriptorSetCount = 1,
.pSetLayouts = &pipeline_hands.descriptor_set_layout,
};
VkDescriptorSet my_descriptor_set;
if (vkAllocateDescriptorSets(device, &descriptor_sets_alloc_info, &my_descriptor_set) != VK_SUCCESS)
abortf("vkAllocateDescriptorSets");
// Configuring my descriptor set, that I just allocated
VkDescriptorBufferInfo buffer_info_for_descriptor_0 = {
VkDescriptorPool descriptor_pool = margaret_create_descriptor_set_pool(device, 1, 2, 2);
VkDescriptorSet descriptor_set_for_pipeline_0 = margaret_allocate_descriptor_set(device, descriptor_pool, pipeline_hands_0.descriptor_set_layout);
VkDescriptorSet descriptor_set_for_pipeline_1 = margaret_allocate_descriptor_set(device, descriptor_pool, pipeline_hands_1.descriptor_set_layout);
// Configuring my descriptor sets, that I just allocated
VkDescriptorBufferInfo buffer_info_for_descriptor_0_in_set_0 = {
.buffer = device_ubo_my_buffer.buffer,
.offset = 0,
.range = sizeof(MyUbo),
};
VkDescriptorImageInfo image_info_for_descriptor_1 = {
VkDescriptorImageInfo image_info_for_descriptor_1_in_set_0 = {
.sampler = my_texture_sampler,
.imageView = wood_texture_view,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
};
VkWriteDescriptorSet descriptor_writes[] = {
VkDescriptorImageInfo image_info_for_descriptor_0_in_set_1 = {
.sampler = my_texture_sampler,
.imageView = IT1_view,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
};
VkWriteDescriptorSet writes_in_descriptor_sets[] = {
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = my_descriptor_set,
.dstSet = descriptor_set_for_pipeline_0,
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.pBufferInfo = &buffer_info_for_descriptor_0,
.pBufferInfo = &buffer_info_for_descriptor_0_in_set_0,
},
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = my_descriptor_set,
.dstSet = descriptor_set_for_pipeline_0,
.dstBinding = 1,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.pImageInfo = &image_info_for_descriptor_1,
.pImageInfo = &image_info_for_descriptor_1_in_set_0,
},
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = descriptor_set_for_pipeline_1,
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.pImageInfo = &image_info_for_descriptor_0_in_set_1,
},
};
vkUpdateDescriptorSets(device, ARRAY_SIZE(descriptor_writes), descriptor_writes, 0, NULL);
vkUpdateDescriptorSets(device, ARRAY_SIZE(writes_in_descriptor_sets), writes_in_descriptor_sets, 0, NULL);
// Mainloop
margaret_ns_time start = margaret_clock_gettime_monotonic_raw();
@ -587,11 +883,11 @@ int main() {
);
if (aq_ret == VK_ERROR_OUT_OF_DATE_KHR) {
fprintf(stderr, "vkAcquireNextImageKHR: VK_ERROR_OUT_OF_DATE_KHR\n");
recreate_swapchain(physical_device, device, queue_fam, surface, render_pass, &swfb);
recreate_swapchain(physical_device, device, queue_fam, surface, render_pass_1, &swfb);
continue;
} else if (aq_ret == VK_SUBOPTIMAL_KHR) {
fprintf(stderr, "vkAcquireNextImageKHR: VK_SUBOPTIMAL_KHR\n");
recreate_swapchain(physical_device, device, queue_fam, surface, render_pass, &swfb);
recreate_swapchain(physical_device, device, queue_fam, surface, render_pass_1, &swfb);
continue;
} else if (aq_ret != VK_SUCCESS) {
abortf("vkAcquireNextImageKHR");
@ -617,8 +913,12 @@ int main() {
vkQueueSubmit(graphics_queue, 1, &ubo_copying_cmd_buffer_submit, NULL);
}
reset_and_record_command_buffer(rendering_command_buffer, render_pass, &pipeline_hands,
*VecVkFramebuffer_cat(&swfb.framebuffers, ij), swfb.extent, &scene, my_descriptor_set);
reset_and_record_command_buffer_0(rendering_command_buffer_0, render_pass_0, &pipeline_hands_0,
IT1_framebuffer, swfb.extent, &scene, descriptor_set_for_pipeline_0);
reset_and_record_command_buffer_1(rendering_command_buffer_1, render_pass_1, &pipeline_hands_1,
*VecVkFramebuffer_cat(&swfb.framebuffers, ij),
swfb.extent, (VkExtent2D){.width = MAX_WIN_WIDTH, .height = MAX_WIN_HEIGHT}, descriptor_set_for_pipeline_1);
{
VkSemaphore waiting_for_semaphores[2] = {
@ -630,8 +930,8 @@ int main() {
};
assert(ARRAY_SIZE(waiting_for_semaphores) == ARRAY_SIZE(waiting_stages));
// VkCommandBuffer command_buffers[1] = {*VecVkCommandBuffer_cat(&rendering_command_buffers, ij)};
VkCommandBuffer command_buffers[1] = {rendering_command_buffer};
VkSemaphore signaling_semaphores[1] = { swfb.render_finished_semaphore };
VkCommandBuffer command_buffers[1] = {rendering_command_buffer_0};
VkSemaphore signaling_semaphores[1] = { swfb.rendered_to_IT1_semaphore };
VkSubmitInfo cmd_submit_info = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
@ -648,6 +948,30 @@ int main() {
.signalSemaphoreCount = ARRAY_SIZE(signaling_semaphores),
.pSignalSemaphores = signaling_semaphores,
};
if (vkQueueSubmit(graphics_queue, 1, &cmd_submit_info, NULL) != VK_SUCCESS)
abortf("vkQueueSubmit");
}
{
VkSemaphore waiting_for_semaphores[1] = { swfb.rendered_to_IT1_semaphore };
VkPipelineStageFlags waiting_stages[1] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
assert(ARRAY_SIZE(waiting_for_semaphores) == ARRAY_SIZE(waiting_stages));
VkCommandBuffer command_buffers[1] = { rendering_command_buffer_1 };
VkSemaphore signaling_semaphores[1] = { swfb.render_finished_semaphore };
VkSubmitInfo cmd_submit_info = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.waitSemaphoreCount = ARRAY_SIZE(waiting_for_semaphores),
.pWaitSemaphores = waiting_for_semaphores,
.pWaitDstStageMask = waiting_stages,
.commandBufferCount = ARRAY_SIZE(command_buffers),
.pCommandBuffers = command_buffers,
.signalSemaphoreCount = ARRAY_SIZE(signaling_semaphores),
.pSignalSemaphores = signaling_semaphores,
};
if (vkQueueSubmit(graphics_queue, 1, &cmd_submit_info, swfb.in_flight_fence) != VK_SUCCESS)
abortf("vkQueueSubmit");
}
@ -670,13 +994,14 @@ int main() {
};
VkResult pres_ret = vkQueuePresentKHR(presentation_queue, &present_info);
// todo: ponder more over this
if (pres_ret == VK_ERROR_OUT_OF_DATE_KHR) {
fprintf(stderr, "vkQueuePresentKHR: VK_ERROR_OUT_OF_DATE_KHR\n");
recreate_swapchain(physical_device, device, queue_fam, surface, render_pass, &swfb);
recreate_swapchain(physical_device, device, queue_fam, surface, render_pass_1, &swfb);
continue;
} else if (pres_ret == VK_SUBOPTIMAL_KHR) {
fprintf(stderr, "vkQueuePresentKHR: VK_SUBOPTIMAL_KHR\n");
recreate_swapchain(physical_device, device, queue_fam, surface, render_pass, &swfb);
recreate_swapchain(physical_device, device, queue_fam, surface, render_pass_1, &swfb);
continue;
} else if (pres_ret != VK_SUCCESS) {
abortf("vkQueuePresentKHR");
@ -712,6 +1037,7 @@ int main() {
vkDestroyBuffer(device, device_ebo_2_buffer.buffer, NULL);
vkDestroyBuffer(device, device_ubo_my_buffer.buffer, NULL);
vkDestroyImage(device, device_wood_texture.image, NULL);
vkDestroyImage(device, device_IT1_image.image, NULL);
vkDestroyBuffer(device, host_mem_buffer.buffer, NULL);
vkFreeMemory(device, device_mem, NULL);
@ -719,8 +1045,10 @@ int main() {
vkFreeMemory(device, host_mem, NULL);
vkDestroyCommandPool(device, command_pool, NULL);
MargaretSwapchainBundle_drop_with_device(device, swfb);
destroy_graphics_pipeline_hands(device, pipeline_hands);
vkDestroyRenderPass(device, render_pass, NULL);
destroy_graphics_pipeline_hands(device, pipeline_hands_1);
vkDestroyRenderPass(device, render_pass_1, NULL);
destroy_graphics_pipeline_hands(device, pipeline_hands_0);
vkDestroyRenderPass(device, render_pass_0, NULL);
vkDestroyDevice(device, NULL);
vkDestroySurfaceKHR(instance, surface, NULL);
MargaretInstanceAndItsDebug_drop(inst_hands);

View File

@ -1,4 +1,11 @@
#!/usr/bin/env bash
cd test_shaders
glslc -o spv/0/vert.spv glsl/0/0.vert
glslc -o spv/0/frag.spv glsl/0/0.frag
function compile(){
mkdir -p "spv/$1"
glslc -o "spv/$1/vert.spv" "glsl/$1/$1.vert"
glslc -o "spv/$1/frag.spv" "glsl/$1/$1.frag"
}
compile 0
compile 1

View File

@ -4,14 +4,6 @@ layout(location = 0) in vec2 fsin_tex;
layout(location = 0) out vec4 fin_color;
layout(binding = 0) uniform my_ubo {
vec3 s; // 0 + 12 + 4
};
layout(binding = 1) uniform sampler2D wood_texture;
void main() {
vec2 tex_offset = 1.0 / textureSize(wood_texture, 0);
fin_color = texture(wood_texture, gl_FragCoord.xy * tex_offset);
}
void main(){
fin_color = vec4(fsin_tex, 0, 1);
}

View File

@ -5,7 +5,10 @@ layout(location = 1) in vec2 tex;
layout(location = 0) out vec2 vsout_tex;
void main() {
gl_Position = vec4(pos, 1.0);
// todo: add my ubo (location = 0) into the mix
// todo: add my woiod_texture (location = 1) into the mix
void main(){
vsout_tex = tex;
}
gl_Position = vec4(pos, 1);
}

View File

@ -0,0 +1,15 @@
#version 450
layout(location = 0) in vec2 fsin_tex;
layout(location = 0) out vec4 fin_color;
layout(binding = 0) uniform sampler2D prev;
void main() {
vec2 tex_offset = 1.0 / textureSize(prev, 0);
// fin_color = texture(wood_texture, gl_FragCoord.xy * tex_offset);
fin_color = (texture(prev, fsin_tex + tex_offset * vec2(1, 0)) + texture(prev, fsin_tex + tex_offset * vec2(-1, 0)) +
texture(prev, fsin_tex + tex_offset * vec2(0, 1)) + texture(prev, fsin_tex + tex_offset * vec2(0, -1)) - 4 *
texture(prev, fsin_tex + tex_offset * vec2(0, 0))) / 8;
}

View File

@ -0,0 +1,20 @@
#version 450
vec2 big_triangle_pos[3] = vec2[](
vec2(-1, -1), vec2(-1, 3), vec2(3, -1)
);
vec2 big_triangle_tex[3] = vec2[](
vec2(0, 1), vec2(0, -1), vec2(2, 1)
);
layout(location = 0) out vec2 vsout_tex;
layout(push_constant, std430) uniform pc {
vec2 region_tex_scale;
};
void main() {
vsout_tex = big_triangle_tex[gl_VertexIndex] * region_tex_scale;
gl_Position = vec4(big_triangle_pos[gl_VertexIndex], 0, 1);
}