Skip to content

Commit

Permalink
More rage-hacking, ripping out things and putting them in main()
Browse files Browse the repository at this point in the history
Most overrides are now passed in from main, which is very good. Soon we
can rewrite the args parser to not have that awful global state.
main.c is getting awfully cluttered though, but that will be resolved
over time. We just have to trust the process.
I'm also moving pretty fast, so I'm likely adding lots of bugs, I'll
work on those once I've got the API and lib/driver separation to a
satisfactory state.
  • Loading branch information
vkoskiv committed Nov 13, 2023
1 parent 06fe172 commit 930dc37
Show file tree
Hide file tree
Showing 12 changed files with 202 additions and 164 deletions.
2 changes: 2 additions & 0 deletions include/c-ray/c-ray.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ enum cr_renderer_param {
cr_renderer_override_height,
cr_renderer_should_save, //FIXME: Remove
cr_renderer_override_cam,
cr_renderer_node_list,
cr_renderer_scene_cache, // FIXME: Remove
};

bool cr_renderer_set_num_pref(struct cr_renderer *ext, enum cr_renderer_param p, uint64_t num);
Expand Down
45 changes: 45 additions & 0 deletions src/accelerators/bvh.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
#include "../datatypes/mesh.h"
#include "../renderer/instance.h"
#include "../datatypes/vector.h"
#include "../utils/platform/thread.h"
#include "../utils/platform/signal.h"
#include "../utils/timer.h"

#include <limits.h>
#include <assert.h>
Expand Down Expand Up @@ -643,3 +646,45 @@ void destroy_bvh(struct bvh *bvh) {
free(bvh);
}
}

struct bvh_build_task {
struct bvh *bvh;
const struct mesh *mesh;
};

void *bvh_build_thread(void *arg) {
block_signals();
struct bvh_build_task *task = (struct bvh_build_task *)thread_user_data(arg);
task->bvh = build_mesh_bvh(task->mesh);
return NULL;
}

void compute_accels(struct mesh_arr meshes) {
logr(info, "Computing BVHs: ");
struct timeval timer = { 0 };
timer_start(&timer);
struct bvh_build_task *tasks = calloc(meshes.count, sizeof(*tasks));
struct cr_thread *build_threads = calloc(meshes.count, sizeof(*build_threads));
for (size_t t = 0; t < meshes.count; ++t) {
tasks[t] = (struct bvh_build_task){
.mesh = &meshes.items[t],
};
build_threads[t] = (struct cr_thread){
.thread_fn = bvh_build_thread,
.user_data = &tasks[t]
};
if (thread_start(&build_threads[t])) {
logr(error, "Failed to create a bvhBuildTask\n");
}
}

for (size_t t = 0; t < meshes.count; ++t) {
thread_wait(&build_threads[t]);
meshes.items[t].bvh = tasks[t].bvh;
}
printSmartTime(timer_get_ms(timer));
free(tasks);
free(build_threads);
logr(plain, "\n");
}

2 changes: 2 additions & 0 deletions src/accelerators/bvh.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ bool traverse_bottom_level_bvh(

/// Frees the memory allocated by the given BVH
void destroy_bvh(struct bvh *);

void compute_accels(struct mesh_arr meshes);
13 changes: 11 additions & 2 deletions src/api/c-ray.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,16 @@ bool cr_renderer_set_str_pref(struct cr_renderer *ext, enum cr_renderer_param p,
}
return true;
}
case cr_renderer_node_list: {
if (r->prefs.node_list) free(r->prefs.node_list);
r->prefs.node_list = stringCopy(str);
return true;
}
case cr_renderer_scene_cache: {
if (r->sceneCache) free(r->sceneCache);
r->sceneCache = stringCopy(str);
return true;
}
default: {
logr(warning, "Renderer param %i not a string\n", p);
}
Expand Down Expand Up @@ -356,8 +366,7 @@ void cr_load_mesh_from_buf(char *buf) {

struct texture *cr_renderer_render(struct cr_renderer *ext) {
struct renderer *r = (struct renderer *)ext;
if (args_is_set("use_clustering")) {
r->prefs.useClustering = true;
if (r->prefs.node_list) {
r->state.clients = syncWithClients(r, &r->state.clientCount);
free(r->sceneCache);
r->sceneCache = NULL;
Expand Down
70 changes: 68 additions & 2 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ int main(int argc, char *argv[]) {
goto done;
}

if (args_is_set("cam_index")) {
cr_renderer_set_num_pref(renderer, cr_renderer_override_cam, args_int("cam_index"));
}

// FIXME: Remove global options table, store it in a local in main() and run overrides
// from there.

Expand Down Expand Up @@ -114,9 +118,71 @@ int main(int argc, char *argv[]) {
}
}

if (args_is_set("cam_index")) {
cr_renderer_set_num_pref(renderer, cr_renderer_override_cam, args_int("cam_index"));
// This is where we prepare a cache of scene data to be sent to worker nodes
// We also apply any potential command-line overrides to that cache here as well.
// FIXME: This overrides setting should be integrated with scene loading, probably.
if (args_is_set("nodes_list")) {
cr_renderer_set_str_pref(renderer, cr_renderer_node_list, args_string("nodes_list"));
// Stash a cache of scene data here
// Apply overrides to the cache here
if (args_is_set("samples_override")) {
cJSON *renderer = cJSON_GetObjectItem(scene, "renderer");
if (cJSON_IsObject(renderer)) {
int samples = args_int("samples_override");
logr(debug, "Overriding cache sample count to %i\n", samples);
if (cJSON_IsNumber(cJSON_GetObjectItem(renderer, "samples"))) {
cJSON_ReplaceItemInObject(renderer, "samples", cJSON_CreateNumber(samples));
} else {
cJSON_AddItemToObject(renderer, "samples", cJSON_CreateNumber(samples));
}
}
}

if (args_is_set("dims_override")) {
cJSON *renderer = cJSON_GetObjectItem(scene, "renderer");
if (cJSON_IsObject(renderer)) {
int width = args_int("dims_width");
int height = args_int("dims_height");
logr(info, "Overriding cache image dimensions to %ix%i\n", width, height);
if (cJSON_IsNumber(cJSON_GetObjectItem(renderer, "width")) && cJSON_IsNumber(cJSON_GetObjectItem(renderer, "height"))) {
cJSON_ReplaceItemInObject(renderer, "width", cJSON_CreateNumber(width));
cJSON_ReplaceItemInObject(renderer, "height", cJSON_CreateNumber(height));
} else {
cJSON_AddItemToObject(renderer, "width", cJSON_CreateNumber(width));
cJSON_AddItemToObject(renderer, "height", cJSON_CreateNumber(height));
}
}
}

if (args_is_set("tiledims_override")) {
cJSON *renderer = cJSON_GetObjectItem(scene, "renderer");
if (cJSON_IsObject(renderer)) {
int width = args_int("tile_width");
int height = args_int("tile_height");
logr(info, "Overriding cache tile dimensions to %ix%i\n", width, height);
if (cJSON_IsNumber(cJSON_GetObjectItem(renderer, "tileWidth")) && cJSON_IsNumber(cJSON_GetObjectItem(renderer, "tileHeight"))) {
cJSON_ReplaceItemInObject(renderer, "tileWidth", cJSON_CreateNumber(width));
cJSON_ReplaceItemInObject(renderer, "tileHeight", cJSON_CreateNumber(height));
} else {
cJSON_AddItemToObject(renderer, "tileWidth", cJSON_CreateNumber(width));
cJSON_AddItemToObject(renderer, "tileHeight", cJSON_CreateNumber(height));
}
}
}

if (args_is_set("cam_index")) {
cJSON_AddItemToObject(scene, "selected_camera", cJSON_CreateNumber(args_int("cam_index")));
}

// Store cache. This is what gets sent to worker nodes.
char *cache = cJSON_PrintUnformatted(scene);
cr_renderer_set_str_pref(renderer, cr_renderer_scene_cache, cache);
free(cache);
}

logr(debug, "Deleting JSON...\n");
cJSON_Delete(scene);
logr(debug, "Deleting done\n");

struct timeval timer;
timer_start(&timer);
Expand Down
38 changes: 38 additions & 0 deletions src/renderer/renderer.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "../utils/platform/signal.h"
#include "../utils/protocol/server.h"
#include "../utils/string.h"
#include "../accelerators/bvh.h"

//Main thread loop speeds
#define paused_msec 100
Expand All @@ -44,6 +45,29 @@ void sigHandler(int sig) {
}
}

static void printSceneStats(struct world *scene, unsigned long long ms) {
logr(info, "Scene construction completed in ");
printSmartTime(ms);
uint64_t polys = 0;
uint64_t vertices = 0;
uint64_t normals = 0;
for (size_t i = 0; i < scene->instances.count; ++i) {
if (isMesh(&scene->instances.items[i])) {
const struct mesh *mesh = &scene->meshes.items[scene->instances.items[i].object_idx];
polys += mesh->polygons.count;
vertices += mesh->vbuf->vertices.count;
normals += mesh->vbuf->normals.count;
}
}
logr(plain, "\n");
logr(info, "Totals: %liV, %liN, %zuI, %liP, %zuS, %zuM\n",
vertices,
normals,
scene->instances.count,
polys,
scene->spheres.count,
scene->meshes.count);
}

void *renderThread(void *arg);
void *renderThreadInteractive(void *arg);
Expand Down Expand Up @@ -92,6 +116,20 @@ struct texture *renderFrame(struct renderer *r) {
r->prefs.tileHeight,
r->prefs.tileOrder);

// Do some pre-render preparations
// Compute BVH acceleration structures for all meshes in the scene
compute_accels(r->scene->meshes);

// And then compute a single top-level BVH that contains all the objects
logr(info, "Computing top-level BVH: ");
struct timeval timer = {0};
timer_start(&timer);
r->scene->topLevel = build_top_level_bvh(r->scene->instances);
printSmartTime(timer_get_ms(timer));
logr(plain, "\n");

printSceneStats(r->scene, timer_get_ms(timer));

for (size_t i = 0; i < r->state.tiles.count; ++i)
r->state.tiles.items[i].total_samples = r->prefs.sampleCount;

Expand Down
2 changes: 1 addition & 1 deletion src/renderer/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ struct prefs {
char *assetPath;
size_t imgCount;
enum fileType imgType;
bool useClustering;
char *node_list;
bool isWorker;
struct sdl_prefs window;
};
Expand Down
2 changes: 1 addition & 1 deletion src/utils/args.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ void args_parse(int argc, char **argv) {
logr(debug, "Verbose mode enabled\n");

if (args_is_set("shutdown") && args_is_set("nodes_list")) {
shutdownClients();
shutdownClients(args_string("nodes_list"));
term_restore();
exit(0);
}
Expand Down
Loading

0 comments on commit 930dc37

Please sign in to comment.