solstice-solver

Solver library of the solstice app
git clone git://git.meso-star.com/solstice-solver.git
Log | Files | Refs | README | LICENSE

commit c628c73deac8ebecdb3f3a3322d903c08113af1c
parent 389c9fe6811e0655d250048eeb8f88cd1dcde86c
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed,  8 Mar 2017 15:32:35 +0100

Major refactoring of the draw functions

Provide a ssol_draw_draft and ssol_draw_pt functions.

Diffstat:
Mcmake/CMakeLists.txt | 23+++++++++++++++++------
Msrc/ssol.h | 11++++++++++-
Msrc/ssol_device.c | 1+
Msrc/ssol_device_c.h | 2+-
Msrc/ssol_draw.c | 127+++++++++++++------------------------------------------------------------------
Asrc/ssol_draw.h | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/ssol_draw_draft.c | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/ssol_draw_pt.c | 127+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Dsrc/ssol_draw_pt.h | 66------------------------------------------------------------------
Msrc/ssol_object.c | 2++
Msrc/test_ssol_draw.c | 84+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
11 files changed, 365 insertions(+), 241 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -58,6 +58,7 @@ set(SSOL_FILES_SRC ssol_device.c ssol_draw.c ssol_draw_pt.c + ssol_draw_draft.c ssol_estimator.c ssol_image.c ssol_material.c @@ -81,7 +82,7 @@ set(SSOL_FILES_INC ssol_c.h ssol_camera.h ssol_device_c.h - ssol_draw_pt.h + ssol_draw.h ssol_estimator_c.h ssol_image_c.h ssol_material_c.h @@ -126,15 +127,22 @@ rcmake_setup_devel(solstice-solver SolSolver ${VERSION} solstice/ssol_version.h) # Add tests ################################################################################ if(NOT NO_TEST) - function(new_test _name) - add_executable(${_name} - ${SSOL_SOURCE_DIR}/${_name}.c) + function(build_test _name) + add_executable(${_name} ${SSOL_SOURCE_DIR}/${_name}.c) target_link_libraries(${_name} solstice-solver solstice-test RSys Star3D StarSP) - add_test(${_name} ${_name}) + endfunction() + + function(register_test _name) + add_test(${_name} ${ARGN}) rcmake_set_test_runtime_dirs(${_name} _runtime_dirs) endfunction() + function(new_test _name) + build_test(${_name}) + register_test(${_name} ${_name}) + endfunction() + add_library(solstice-test STATIC ${SSOL_SOURCE_DIR}/test_ssol_geometries.h ${SSOL_SOURCE_DIR}/test_ssol_materials.h @@ -145,7 +153,6 @@ if(NOT NO_TEST) new_test(test_ssol_by_receiver_integration) new_test(test_ssol_camera) new_test(test_ssol_device) - new_test(test_ssol_draw) new_test(test_ssol_image) new_test(test_ssol_material) new_test(test_ssol_object) @@ -162,6 +169,10 @@ if(NOT NO_TEST) new_test(test_ssol_solver5) new_test(test_ssol_solver6) new_test(test_ssol_sun) + + build_test(test_ssol_draw) + register_test(test_ssol_draw_draft test_ssol_draw draft) + endif() ################################################################################ diff --git a/src/ssol.h b/src/ssol.h @@ -951,7 +951,16 @@ ssol_solve struct ssol_estimator** estimator); SSOL_API res_T -ssol_draw +ssol_draw_draft + (struct ssol_scene* scn, + struct ssol_camera* cam, + const size_t width, /* #pixels in X */ + const size_t height, /* #pixels in Y */ + ssol_write_pixels_T writer, + void* writer_data); + +SSOL_API res_T +ssol_draw_pt (struct ssol_scene* scn, struct ssol_camera* cam, const size_t width, /* #pixels in X */ diff --git a/src/ssol_device.c b/src/ssol_device.c @@ -19,6 +19,7 @@ #include <rsys/logger.h> #include <rsys/mem_allocator.h> +#include <star/s3d.h> #include <star/scpr.h> #include <omp.h> diff --git a/src/ssol_device_c.h b/src/ssol_device_c.h @@ -19,7 +19,6 @@ #include <rsys/dynamic_array.h> #include <rsys/free_list.h> #include <rsys/ref_count.h> -#include <star/s3d.h> #define DARRAY_NAME byte #define DARRAY_DATA char @@ -35,6 +34,7 @@ #include <rsys/dynamic_array.h> struct scpr_mesh; +struct s3d_device; struct ssol_device { struct logger* logger; diff --git a/src/ssol_draw.c b/src/ssol_draw.c @@ -14,19 +14,10 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "ssol.h" -#include "ssol_c.h" -#include "ssol_camera.h" #include "ssol_device_c.h" -#include "ssol_draw_pt.h" -#include "ssol_material_c.h" -#include "ssol_object_c.h" +#include "ssol_draw.h" #include "ssol_scene_c.h" -#include "ssol_shape_c.h" -#include "ssol_sun_c.h" -#include <rsys/double2.h> -#include <rsys/double3.h> -#include <rsys/math.h> #include <star/s3d.h> #include <omp.h> @@ -51,61 +42,23 @@ morton2D_decode(const uint32_t u32) } static void -Li_basic - (struct ssol_scene* scn, - struct s3d_scene_view* view, - const float org[3], - const float dir[3], - double val[3]) -{ - const float range[2] = {0, FLT_MAX}; - struct ray_data ray_data = RAY_DATA_NULL; - struct s3d_hit hit; - ASSERT(scn && view && org && dir && val); - - ray_data.scn = scn; - ray_data.discard_virtual_materials = 1; - S3D(scene_view_trace_ray(view, org, dir, range, &ray_data, &hit)); - if(S3D_HIT_NONE(&hit)) { - d3_splat(val, 0); - } else { - struct ssol_instance* inst; - const struct shaded_shape* sshape; - size_t isshape; - float N[3]={0}; - - /* Retrieve the hit shaded shape */ - inst = *htable_instance_find(&scn->instances_rt, &hit.prim.inst_id); - isshape = *htable_shaded_shape_find - (&inst->object->shaded_shapes_rt, &hit.prim.geom_id); - sshape = darray_shaded_shape_cdata_get - (&inst->object->shaded_shapes) + isshape; - - /* Retrieve and normalized the hit normal */ - switch(sshape->shape->type) { - case SHAPE_MESH: f3_normalize(N, hit.normal); break; - case SHAPE_PUNCHED: f3_normalize(N, f3_set_d3(N, ray_data.N)); break; - default: FATAL("Unreachable code"); break; - } - ASSERT(f3_is_normalized(N)); - d3_splat(val, fabs(f3_dot(N, dir))); - } -} - -static void draw_tile (struct ssol_scene* scn, - struct draw_pt_thread_context* ctx, struct s3d_scene_view* view, const struct ssol_camera* cam, + const int ithread, + const size_t spp, const size_t origin[2], /* Tile origin */ const size_t size[2], /* Tile definition */ const float pix_sz[2], /* Normalized size of a pixel in the image plane */ - double* pixels) + double* pixels, + pixel_shader_T shader, + void* shader_data) { size_t npixels; size_t mcode; /* Morton code of the tile pixel */ - ASSERT(scn && ctx && view && cam && origin && size && pix_sz && pixels); + ASSERT(scn && view && cam && spp && origin && size && pix_sz && pixels); + ASSERT(shader); /* Adjust the #pixels to process them wrt a morton order */ npixels = round_up_pow2(MMAX(size[0], size[1])); @@ -124,37 +77,25 @@ draw_tile ipix[0] = ipix[0] + origin[0]; ipix[1] = ipix[1] + origin[1]; -#if 0 - draw_pt(scn, cam, view, ipix, pix_sz, 64, ctx, pixel); -#else - { - float samp[2]; - float ray_org[3], ray_dir[3]; - - samp[0] = ((float)ipix[0] + 0.5f) * pix_sz[0]; - samp[1] = ((float)ipix[1] + 0.5f) * pix_sz[1]; - camera_ray(cam, samp, ray_org, ray_dir); - - Li_basic(scn, view, ray_org, ray_dir, pixel); - } -#endif + shader(scn, cam, view, ithread, ipix, pix_sz, spp, pixel, shader_data); } } /******************************************************************************* - * Exported function + * Local function ******************************************************************************/ res_T -ssol_draw +draw (struct ssol_scene* scn, - struct ssol_camera* cam, + const struct ssol_camera* cam, const size_t width, const size_t height, + const size_t spp, /* #samples per pixel */ ssol_write_pixels_T writer, - void* data) + void* writer_data, + pixel_shader_T pixel_shader, + void* pixel_shader_data) { - struct darray_draw_pt_thread_context thread_ctxs; - struct ssp_rng_proxy* rng_proxy = NULL; struct s3d_scene_view* view = NULL; struct darray_byte* tiles = NULL; int64_t mcode; /* Morton code of a tile */ @@ -163,32 +104,9 @@ ssol_draw size_t i; ATOMIC res = RES_OK; - if(!scn || !cam || !width || !height || !writer) + if(!scn || !cam || !width || !height || !spp || !writer || !pixel_shader) return RES_BAD_ARG; - darray_draw_pt_thread_context_init(scn->dev->allocator, &thread_ctxs); - - /* Create a RNG proxy */ - res = ssp_rng_proxy_create - (scn->dev->allocator, &ssp_rng_threefry, scn->dev->nthreads, &rng_proxy); - if(res != RES_OK) goto error; - - /* Create the thread contexts */ - res = darray_draw_pt_thread_context_resize(&thread_ctxs, scn->dev->nthreads); - if(res != RES_OK) goto error; - FOR_EACH(i, 0, scn->dev->nthreads) { - struct draw_pt_thread_context* ctx; - struct ssp_rng* rng; - - ctx = darray_draw_pt_thread_context_data_get(&thread_ctxs)+i; - - res = ssp_rng_proxy_create_rng(rng_proxy, i, &rng); - if(res != RES_OK) goto error; - - draw_pt_thread_context_setup(ctx, rng); - SSP(rng_ref_put(rng)); - } - tiles = darray_tile_data_get(&scn->dev->tiles); ASSERT(darray_tile_size_get(&scn->dev->tiles) == scn->dev->nthreads); FOR_EACH(i, 0, scn->dev->nthreads) { @@ -210,7 +128,6 @@ ssol_draw #pragma omp parallel for schedule(dynamic, 1/*chunck size*/) for(mcode=0; mcode<(int64_t)ntiles; ++mcode) { - struct draw_pt_thread_context* ctx; size_t tile_org[2]; size_t tile_sz[2]; const int ithread = omp_get_thread_num(); @@ -219,8 +136,6 @@ ssol_draw if(ATOMIC_GET(&res) != RES_OK) continue; - ctx = darray_draw_pt_thread_context_data_get(&thread_ctxs) + ithread; - tile_org[0] = morton2D_decode((uint32_t)(mcode>>0)); if(tile_org[0] >= ntiles_x) continue; tile_org[1] = morton2D_decode((uint32_t)(mcode>>1)); @@ -233,9 +148,10 @@ ssol_draw pixels = (double*)darray_byte_data_get(tiles+ithread); - draw_tile(scn, ctx, view, cam, tile_org, tile_sz, pix_sz, pixels); + draw_tile(scn, view, cam, ithread, spp, tile_org, tile_sz, pix_sz, pixels, + pixel_shader, pixel_shader_data); - res_local = writer(data, tile_org, tile_sz, SSOL_PIXEL_DOUBLE3, pixels); + res_local = writer(writer_data, tile_org, tile_sz, SSOL_PIXEL_DOUBLE3, pixels); if(res_local != RES_OK) { ATOMIC_SET(&res, res_local); continue; @@ -243,11 +159,10 @@ ssol_draw } exit: - darray_draw_pt_thread_context_release(&thread_ctxs); - if(rng_proxy) SSP(rng_proxy_ref_put(rng_proxy)); if(view) S3D(scene_view_ref_put(view)); return (res_T)res; error: goto exit; } + diff --git a/src/ssol_draw.h b/src/ssol_draw.h @@ -0,0 +1,52 @@ +/* Copyright (C) CNRS 2016-2017 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef SSOL_DRAW_H +#define SSOL_DRAW_H + +#include "ssol.h" +#include <rsys/rsys.h> + +/* Forward declarations */ +struct s3d_scene_view; +struct ssf_bsdf; +struct ssp_rng; + +typedef void +(*pixel_shader_T) + (struct ssol_scene* scn, + const struct ssol_camera* cam, + struct s3d_scene_view* view, + const int ithread, /* Id of the thread invoking the function */ + const size_t pix_coords[2], /* Image space pixel coordinates */ + const float pix_sz[2], /* Normalized pixel size */ + const size_t nsamples, /* #samples per pixel */ + double pixel[3], /* Output pixel */ + void* ctx); /* User defined data */ + +extern LOCAL_SYM res_T +draw + (struct ssol_scene* scn, + const struct ssol_camera* cam, + const size_t width, + const size_t height, + const size_t spp, + ssol_write_pixels_T writer, + void* writer_data, + pixel_shader_T pixel_shader, + void* pixel_shader_data); + +#endif /* SSOL_DRAW_H */ + diff --git a/src/ssol_draw_draft.c b/src/ssol_draw_draft.c @@ -0,0 +1,111 @@ +/* Copyright (C) CNRS 2016-2017 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "ssol_c.h" +#include "ssol_camera.h" +#include "ssol_draw.h" +#include "ssol_object_c.h" +#include "ssol_scene_c.h" +#include "ssol_shape_c.h" + +#include <rsys/double3.h> +#include <rsys/float3.h> + +#include <float.h> + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static void +Li + (struct ssol_scene* scn, + struct s3d_scene_view* view, + const float org[3], + const float dir[3], + double val[3]) +{ + const float range[2] = {0, FLT_MAX}; + struct ray_data ray_data = RAY_DATA_NULL; + struct s3d_hit hit; + ASSERT(scn && view && org && dir && val); + + ray_data.scn = scn; + ray_data.discard_virtual_materials = 1; + S3D(scene_view_trace_ray(view, org, dir, range, &ray_data, &hit)); + if(S3D_HIT_NONE(&hit)) { + d3_splat(val, 0); + } else { + struct ssol_instance* inst; + const struct shaded_shape* sshape; + size_t isshape; + float N[3]={0}; + + /* Retrieve the hit shaded shape */ + inst = *htable_instance_find(&scn->instances_rt, &hit.prim.inst_id); + isshape = *htable_shaded_shape_find + (&inst->object->shaded_shapes_rt, &hit.prim.geom_id); + sshape = darray_shaded_shape_cdata_get + (&inst->object->shaded_shapes) + isshape; + + /* Retrieve and normalized the hit normal */ + switch(sshape->shape->type) { + case SHAPE_MESH: f3_normalize(N, hit.normal); break; + case SHAPE_PUNCHED: f3_normalize(N, f3_set_d3(N, ray_data.N)); break; + default: FATAL("Unreachable code"); break; + } + ASSERT(f3_is_normalized(N)); + d3_splat(val, fabs(f3_dot(N, dir))); + } +} + +static void +draw_pixel + (struct ssol_scene* scn, + const struct ssol_camera* cam, + struct s3d_scene_view* view, + const int ithread, + const size_t pix_coords[2], /* Image space pixel coordinates */ + const float pix_sz[2], /* Normalized pixel size */ + const size_t nsamples, + double pixel[3], + void* ctx) +{ + float samp[2]; + float ray_org[3], ray_dir[3]; + ASSERT(scn && cam && view && pix_coords && pix_sz && nsamples && pixel); + (void)ithread, (void)ctx, (void)nsamples; + + samp[0] = ((float)pix_coords[0] + 0.5f) * pix_sz[0]; + samp[1] = ((float)pix_coords[1] + 0.5f) * pix_sz[1]; + camera_ray(cam, samp, ray_org, ray_dir); + Li(scn, view, ray_org, ray_dir, pixel); +} + + +/******************************************************************************* + * Exported function + ******************************************************************************/ +res_T +ssol_draw_draft + (struct ssol_scene* scn, + struct ssol_camera* cam, + const size_t width, + const size_t height, + ssol_write_pixels_T writer, + void* data) +{ + return draw(scn, cam, width, height, 1, writer, data, draw_pixel, NULL); +} + diff --git a/src/ssol_draw_pt.c b/src/ssol_draw_pt.c @@ -15,7 +15,8 @@ #include "ssol_c.h" #include "ssol_camera.h" -#include "ssol_draw_pt.h" +#include "ssol_device_c.h" +#include "ssol_draw.h" #include "ssol_material_c.h" #include "ssol_object_c.h" #include "ssol_scene_c.h" @@ -33,10 +34,23 @@ /******************************************************************************* * Per thread draw_pt context ******************************************************************************/ -res_T -draw_pt_thread_context_init +struct thread_context { + struct ssp_rng* rng; + struct ssf_bsdf* bsdf; +}; + +static void +thread_context_release(struct thread_context* ctx) +{ + ASSERT(ctx); + if(ctx->rng) SSP(rng_ref_put(ctx->rng)); + if(ctx->bsdf) SSF(bsdf_ref_put(ctx->bsdf)); +} + +static res_T +thread_context_init (struct mem_allocator* allocator, - struct draw_pt_thread_context* ctx) + struct thread_context* ctx) { res_T res = RES_OK; ASSERT(ctx); @@ -46,22 +60,13 @@ draw_pt_thread_context_init exit: return res; error: - draw_pt_thread_context_release(ctx); + thread_context_release(ctx); goto exit; } -void -draw_pt_thread_context_release(struct draw_pt_thread_context* ctx) -{ - ASSERT(ctx); - if(ctx->rng) SSP(rng_ref_put(ctx->rng)); - if(ctx->bsdf) SSF(bsdf_ref_put(ctx->bsdf)); -} - - -void -draw_pt_thread_context_setup - (struct draw_pt_thread_context* ctx, +static void +thread_context_setup + (struct thread_context* ctx, struct ssp_rng* rng) { ASSERT(ctx && rng); @@ -70,6 +75,13 @@ draw_pt_thread_context_setup ctx->rng = rng; } +/* Declare the container of the per thread contexts */ +#define DARRAY_NAME thread_context +#define DARRAY_DATA struct thread_context +#define DARRAY_FUNCTOR_INIT thread_context_init +#define DARRAY_FUNCTOR_RELEASE thread_context_release +#include <rsys/dynamic_array.h> + /******************************************************************************* * Helper functions ******************************************************************************/ @@ -105,9 +117,8 @@ sun_lighting } static void -Li - (struct ssol_scene* scn, - struct draw_pt_thread_context* ctx, +Li(struct ssol_scene* scn, + struct thread_context* ctx, struct s3d_scene_view* view, const float org[3], const float dir[3], @@ -213,25 +224,28 @@ Li d3_splat(val, L); } -/******************************************************************************* - * Local function - ******************************************************************************/ -void -draw_pt +static void +draw_pixel (struct ssol_scene* scn, const struct ssol_camera* cam, struct s3d_scene_view* view, + const int ithread, const size_t pix_coords[2], /* Image space pixel coordinates */ const float pix_sz[2], /* Normalized pixel size */ const size_t nsamples, - struct draw_pt_thread_context* ctx, - double pixel[3]) + double pixel[3], + void* data) { + struct darray_thread_context* thread_ctxs = data; + struct thread_context* ctx; double L[3]; size_t isample; - ASSERT(scn && cam && pix_coords && pix_sz && nsamples && ctx && pixel); + ASSERT(scn && cam && pix_coords && pix_sz && nsamples && pixel && ctx); + ASSERT((size_t)ithread < darray_thread_context_size_get(thread_ctxs)); + ctx = darray_thread_context_data_get(thread_ctxs) + ithread; d3_splat(pixel, 0); + FOR_EACH(isample, 0, nsamples) { float samp[2]; /* Pixel sample */ float ray_org[3], ray_dir[3]; @@ -249,5 +263,60 @@ draw_pt d3_add(pixel, pixel, L); } - d3_divd(pixel, pixel, (double)nsamples); + d3_divd(pixel, pixel, (double)nsamples); /* Expected value */ +} + +/******************************************************************************* + * Exported function + ******************************************************************************/ +res_T +ssol_draw_pt + (struct ssol_scene* scn, + struct ssol_camera* cam, + const size_t width, + const size_t height, + ssol_write_pixels_T writer, + void* data) +{ + struct darray_thread_context thread_ctxs; + struct ssp_rng_proxy* rng_proxy = NULL; + size_t i; + res_T res = RES_OK; + + if(!scn) + return RES_BAD_ARG; + + darray_thread_context_init(scn->dev->allocator, &thread_ctxs); + + /* Create a RNG proxy */ + res = ssp_rng_proxy_create + (scn->dev->allocator, &ssp_rng_threefry, scn->dev->nthreads, &rng_proxy); + if(res != RES_OK) goto error; + + /* Create the thread contexts */ + res = darray_thread_context_resize(&thread_ctxs, scn->dev->nthreads); + if(res != RES_OK) goto error; + FOR_EACH(i, 0, scn->dev->nthreads) { + struct thread_context* ctx; + struct ssp_rng* rng; + + ctx = darray_thread_context_data_get(&thread_ctxs)+i; + + res = ssp_rng_proxy_create_rng(rng_proxy, i, &rng); + if(res != RES_OK) goto error; + + thread_context_setup(ctx, rng); + SSP(rng_ref_put(rng)); + } + + /* Invoke the draw process */ + res = draw(scn, cam, width, height, 4, writer, data, draw_pixel, &thread_ctxs); + if(res != RES_OK) goto error; + +exit: + darray_thread_context_release(&thread_ctxs); + if(rng_proxy) SSP(rng_proxy_ref_put(rng_proxy)); + return (res_T)res; +error: + goto exit; } diff --git a/src/ssol_draw_pt.h b/src/ssol_draw_pt.h @@ -1,66 +0,0 @@ -/* Copyright (C) CNRS 2016-2017 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifndef SSOL_DRAW_PT_H -#define SSOL_DRAW_PT_H - -#include <rsys/dynamic_array.h> - -/* Forward declarations */ -struct s3d_scene_view; -struct ssol_camera; -struct ssol_scene; -struct ssf_bsdf; -struct ssp_rng; - -struct draw_pt_thread_context { - struct ssp_rng* rng; - struct ssf_bsdf* bsdf; -}; - -extern LOCAL_SYM res_T -draw_pt_thread_context_init - (struct mem_allocator* allocator, - struct draw_pt_thread_context* ctx); - -extern LOCAL_SYM void -draw_pt_thread_context_release - (struct draw_pt_thread_context* ctx); - -extern LOCAL_SYM void -draw_pt_thread_context_setup - (struct draw_pt_thread_context* ctx, - struct ssp_rng* rng); - -/* Declare the container of the per thread contexts */ -#define DARRAY_NAME draw_pt_thread_context -#define DARRAY_DATA struct draw_pt_thread_context -#define DARRAY_FUNCTOR_INIT draw_pt_thread_context_init -#define DARRAY_FUNCTOR_RELEASE draw_pt_thread_context_release -#include <rsys/dynamic_array.h> - -extern LOCAL_SYM void -draw_pt - (struct ssol_scene* scn, - const struct ssol_camera* cam, - struct s3d_scene_view* view, - const size_t pix_coords[2], - const float pix_sz[2], - const size_t nsamples, - struct draw_pt_thread_context* ctx, - double radiance[3]); - -#endif /* SSOL_DRAW_PT_H */ - diff --git a/src/ssol_object.c b/src/ssol_object.c @@ -18,6 +18,8 @@ #include "ssol_object_c.h" #include "ssol_shape_c.h" +#include <star/s3d.h> + #include <rsys/ref_count.h> #include <rsys/rsys.h> #include <rsys/mem_allocator.h> diff --git a/src/test_ssol_draw.c b/src/test_ssol_draw.c @@ -23,6 +23,8 @@ #include <rsys/image.h> #include <rsys/math.h> +#include <string.h> + #define WIDTH 800 #define HEIGHT 600 #define PITCH (WIDTH*sizeof(unsigned char[3])) @@ -186,8 +188,26 @@ main(int argc, char** argv) const double tgt[3] = {278.0, 0.0, 273.0}; const double up[3] = {0.0, 0.0, 1.0}; double dir[3]; + res_T (*draw_func) + (struct ssol_scene* scn, + struct ssol_camera* cam, + const size_t width, + const size_t height, + ssol_write_pixels_T writer, + void* data); (void)argc, (void)argv; + if(argc <= 1) { + fprintf(stderr, "Usage: %s <draft|pt>\n", argv[0]); + return -1; + } + + if(!strcmp(argv[1], "draft")) { + draw_func = ssol_draw_draft; + } else if(!strcmp(argv[1], "pt")) { + draw_func = ssol_draw_pt; + } + CHECK(mem_init_proxy_allocator(&allocator, &mem_default_allocator), RES_OK); CHECK(ssol_device_create @@ -212,38 +232,38 @@ main(int argc, char** argv) pixels = MEM_CALLOC(&allocator, HEIGHT, PITCH); NCHECK(pixels, NULL); - CHECK(ssol_draw(NULL, NULL, 0, 0, NULL, pixels), RES_BAD_ARG); - CHECK(ssol_draw(scn, NULL, 0, 0, NULL, pixels), RES_BAD_ARG); - CHECK(ssol_draw(NULL, cam, 0, 0, NULL, pixels), RES_BAD_ARG); - CHECK(ssol_draw(scn, cam, 0, 0, NULL, pixels), RES_BAD_ARG); - CHECK(ssol_draw(NULL, NULL, WIDTH, 0, NULL, pixels), RES_BAD_ARG); - CHECK(ssol_draw(scn, NULL, WIDTH, 0, NULL, pixels), RES_BAD_ARG); - CHECK(ssol_draw(NULL, cam, WIDTH, 0, NULL, pixels), RES_BAD_ARG); - CHECK(ssol_draw(scn, cam, WIDTH, 0, NULL, pixels), RES_BAD_ARG); - CHECK(ssol_draw(NULL, NULL, 0, HEIGHT, NULL, pixels), RES_BAD_ARG); - CHECK(ssol_draw(scn, NULL, 0, HEIGHT, NULL, pixels), RES_BAD_ARG); - CHECK(ssol_draw(NULL, cam, 0, HEIGHT, NULL, pixels), RES_BAD_ARG); - CHECK(ssol_draw(scn, cam, 0, HEIGHT, NULL, pixels), RES_BAD_ARG); - CHECK(ssol_draw(NULL, NULL, WIDTH, HEIGHT, NULL, pixels), RES_BAD_ARG); - CHECK(ssol_draw(scn, NULL, WIDTH, HEIGHT, NULL, pixels), RES_BAD_ARG); - CHECK(ssol_draw(NULL, cam, WIDTH, WIDTH, NULL, pixels), RES_BAD_ARG); - CHECK(ssol_draw(scn, cam, WIDTH, HEIGHT, NULL, pixels), RES_BAD_ARG); - CHECK(ssol_draw(NULL, NULL, 0, 0, write_RGB8, pixels), RES_BAD_ARG); - CHECK(ssol_draw(scn, NULL, 0, 0, write_RGB8, pixels), RES_BAD_ARG); - CHECK(ssol_draw(NULL, cam, 0, 0, write_RGB8, pixels), RES_BAD_ARG); - CHECK(ssol_draw(scn, cam, 0, 0, write_RGB8, pixels), RES_BAD_ARG); - CHECK(ssol_draw(NULL, NULL, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG); - CHECK(ssol_draw(scn, NULL, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG); - CHECK(ssol_draw(NULL, cam, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG); - CHECK(ssol_draw(scn, cam, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG); - CHECK(ssol_draw(NULL, NULL, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); - CHECK(ssol_draw(scn, NULL, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); - CHECK(ssol_draw(NULL, cam, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); - CHECK(ssol_draw(scn, cam, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); - CHECK(ssol_draw(NULL, NULL, WIDTH, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); - CHECK(ssol_draw(scn, NULL, WIDTH, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); - CHECK(ssol_draw(NULL, cam, WIDTH, WIDTH, write_RGB8, pixels), RES_BAD_ARG); - CHECK(ssol_draw(scn, cam, WIDTH, HEIGHT, write_RGB8, pixels), RES_OK); + CHECK(draw_func(NULL, NULL, 0, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, 0, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, 0, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, 0, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, WIDTH, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, WIDTH, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, WIDTH, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, WIDTH, 0, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, 0, HEIGHT, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, 0, HEIGHT, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, 0, HEIGHT, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, 0, HEIGHT, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, WIDTH, HEIGHT, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, WIDTH, HEIGHT, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, WIDTH, WIDTH, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, WIDTH, HEIGHT, NULL, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, 0, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, 0, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, 0, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, 0, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, NULL, WIDTH, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, NULL, WIDTH, HEIGHT, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(NULL, cam, WIDTH, WIDTH, write_RGB8, pixels), RES_BAD_ARG); + CHECK(draw_func(scn, cam, WIDTH, HEIGHT, write_RGB8, pixels), RES_OK); CHECK(image_ppm_write_stream(stdout, WIDTH, HEIGHT, 3, pixels), RES_OK);