From 78dc71bda71fc8eb7accfcf68d010a0fea1a7921 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Sat, 7 Mar 2015 11:21:07 +0100 Subject: Add bucket cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stores accumulation buckets. Use case: Run n seconds, check image noise levels, run again (with cache and thus previous results), check image agin, … --- main.c | 17 +++++++++++++++-- rect.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rect.h | 3 +++ 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index 7a699c3..6a17b3a 100644 --- a/main.c +++ b/main.c @@ -35,6 +35,7 @@ const char *argp_program_version = typedef struct { unsigned int bpc; float scale, time; + char *cache; } render_arguments; static error_t parse_render_opt (int key, char *arg, @@ -68,6 +69,10 @@ static error_t parse_render_opt (int key, char *arg, } break; + case 'c': + arguments->cache = strdup (arg); + break; + case ARGP_KEY_ARG: if (state->arg_num > 0) { return ARGP_ERR_UNKNOWN; @@ -112,8 +117,16 @@ static void do_render (const render_arguments * const arguments) { bucket bucket; bucket_init (&bucket, (uint2) { genome->width, genome->height }); + if (arguments->cache != NULL) { + bucket_deserialize (&bucket, arguments->cache); + } render_bucket (genome, &bucket, arguments->time); + + if (arguments->cache != NULL) { + bucket_serialize (&bucket, arguments->cache); + } + fprintf (stderr, "%lu samples, %lu bad\n", bucket.samples, bucket.badvals); render_image (genome, &bucket, image, bytes_per_channel); @@ -476,8 +489,7 @@ int main (int argc, char **argv) { {"scale", 's', "factor", 0, "Scale image dimensions by factor (1.0)" }, {"bpc", 'b', "8|16", 0, "Bits per channel of output image (8)" }, {"time", 't', "seconds", 0, "Rendering time" }, - {"width", 'w', "pixels", 0, "Output image width" }, - {"height", 'h', "pixels", 0, "Output image height" }, + {"cache", 'c', "path", 0, "Cache file" }, { 0 }, }; const char doc[] = "vlame3-render -- a fractal flame renderer"; @@ -490,6 +502,7 @@ int main (int argc, char **argv) { .bpc = 8, .scale = 1.0, .time = 1.0, + .cache = NULL, }; argp_parse (&argp, argc, argv, 0, NULL, &arguments); diff --git a/rect.c b/rect.c index d988ed1..34bbc7e 100644 --- a/rect.c +++ b/rect.c @@ -194,9 +194,72 @@ void bucket_init (bucket * const b, const uint2 dim) { int ret = posix_memalign ((void **) &b->data, sizeof (*b->data), size); assert (ret == 0); assert (b->data != NULL); + memset (b->data, 0, size); } +/* just a random 32 bit value */ +#define BUCKET_CACHE_IDENT 0x252007d2 + +/* Read bucket from file + */ +bool bucket_deserialize (bucket * const b, const char *file) { + FILE *fd = fopen (file, "r"); + if (fd == NULL) { + return false; + } + + uint32_t ident; + size_t ret = fread (&ident, sizeof (ident), 1, fd); + assert (ret == 1); + assert (ident == BUCKET_CACHE_IDENT); + + uint32_t w, h; + ret = fread (&w, sizeof (w), 1, fd); + assert (ret == 1); + ret = fread (&h, sizeof (h), 1, fd); + assert (ret == 1); + assert (b->dim[0] == w && b->dim[1] == h); + + uint64_t samples, badvals; + ret = fread (&samples, sizeof (samples), 1, fd); + assert (ret == 1); + ret = fread (&badvals, sizeof (badvals), 1, fd); + assert (ret == 1); + b->samples = samples; + b->badvals = badvals; + + ret = fread (b->data, sizeof (*b->data), w*h, fd); + assert (ret == w*h); + + fclose (fd); + + return true; +} + +/* Write bucket into a file + */ +void bucket_serialize (bucket * const b, const char *file) { + FILE *fd = fopen (file, "w"); + assert (fd != NULL); + + uint32_t ident = BUCKET_CACHE_IDENT; + fwrite (&ident, sizeof (ident), 1, fd); + + assert (sizeof (b->dim[0]) >= sizeof (uint32_t)); + fwrite (&b->dim[0], sizeof (uint32_t), 1, fd); + fwrite (&b->dim[1], sizeof (uint32_t), 1, fd); + + assert (sizeof (b->samples) >= sizeof (uint64_t)); + assert (sizeof (b->badvals) >= sizeof (uint64_t)); + fwrite (&b->samples, sizeof (uint64_t), 1, fd); + fwrite (&b->badvals, sizeof (uint64_t), 1, fd); + + fwrite (b->data, sizeof (*b->data), b->dim[0]*b->dim[1], fd); + + fclose (fd); +} + static void compute_camera (const flam3_genome * const genome, const bucket * const bucket, render_constants * const c) { assert (genome != NULL); diff --git a/rect.h b/rect.h index 39c76cb..5b3dd62 100644 --- a/rect.h +++ b/rect.h @@ -11,6 +11,9 @@ typedef struct { } bucket; void bucket_init (bucket * const b, const uint2 dim); +bool bucket_deserialize (bucket * const b, const char *file); +void bucket_serialize (bucket * const b, const char *file); + bool render_bucket (flam3_genome * const genome, bucket * const bucket, const double timelimit); void render_image (const flam3_genome * const genome, const bucket * const b, -- cgit v1.2.3