commit 5937e63bb29b4ac19b5e7d3b444ee0e3c4a2fc06
parent 7d4663a0da5b65c303cc77f9d65d10b66b282e04
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 14 Dec 2016 09:48:27 +0100
Finalize a first version of the ssol_draw function
Diffstat:
4 files changed, 57 insertions(+), 5 deletions(-)
diff --git a/src/ssol.h b/src/ssol.h
@@ -758,6 +758,15 @@ ssol_solve
FILE* output,
struct ssol_estimator* estimator);
+SSOL_API res_T
+ssol_draw
+ (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);
+
END_DECLS
#endif /* SSOL_H */
diff --git a/src/ssol_device.c b/src/ssol_device.c
@@ -48,6 +48,7 @@ device_release(ref_T* ref)
struct ssol_device* dev;
ASSERT(ref);
dev = CONTAINER_OF(ref, struct ssol_device, ref);
+ darray_tile_release(&dev->tiles);
if(dev->s3d) S3D(device_ref_put(dev->s3d));
if(dev->scpr_mesh) SCPR(mesh_ref_put(dev->scpr_mesh));
MEM_RM(dev->allocator, dev);
@@ -80,12 +81,16 @@ ssol_device_create
goto error;
}
ref_init(&dev->ref);
+ darray_tile_init(allocator, &dev->tiles);
dev->logger = logger ? logger : LOGGER_DEFAULT;
dev->allocator = allocator;
dev->verbose = verbose;
dev->nthreads = MMIN(nthreads_hint, (unsigned)omp_get_num_procs());
omp_set_num_threads((int)dev->nthreads);
+ res = darray_tile_resize(&dev->tiles, dev->nthreads);
+ if(res != RES_OK) goto error;
+
res = s3d_device_create(logger, mem_allocator, verbose, &dev->s3d);
if(res != RES_OK) goto error;
diff --git a/src/ssol_device_c.h b/src/ssol_device_c.h
@@ -16,10 +16,24 @@
#ifndef SSOL_DEVICE_C_H
#define SSOL_DEVICE_C_H
+#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
+#define DARRAY_ALIGNMENT 16
+#include <rsys/dynamic_array.h>
+
+#define DARRAY_NAME tile
+#define DARRAY_DATA struct darray_byte
+#define DARRAY_FUNCTOR_INIT darray_byte_init
+#define DARRAY_FUNCTOR_RELEASE darray_byte_release
+#define DARRAY_FUNCTOR_COPY darray_byte_copy
+#define DARRAY_FUNCTOR_COPY_AND_RELEASE darray_byte_copy_and_release
+#include <rsys/dynamic_array.h>
+
struct scpr_mesh;
struct ssol_device {
@@ -28,6 +42,9 @@ struct ssol_device {
unsigned nthreads;
int verbose;
+ /* Per thread draw tile used by the draw function */
+ struct darray_tile tiles;
+
struct s3d_device* s3d;
struct scpr_mesh* scpr_mesh; /* Use to clip quadric mesh */
diff --git a/src/ssol_draw.c b/src/ssol_draw.c
@@ -16,6 +16,8 @@
#include "ssol.h"
#include "ssol_c.h"
#include "ssol_camera.h"
+#include "ssol_device_c.h"
+#include "ssol_scene_c.h"
#include <rsys/double3.h>
#include <rsys/math.h>
@@ -55,7 +57,7 @@ Li(struct ssol_scene* scn,
if(S3D_HIT_NONE(&hit)) {
d3_splat(val, 0);
} else {
- float N[3];
+ float N[3]={0};
f3_normalize(N, hit.normal);
d3_splat(val, fabs(f3_dot(N, dir)));
}
@@ -104,7 +106,7 @@ draw_tile
/*******************************************************************************
* Exported function
******************************************************************************/
-static res_T /* FIXME */
+res_T
ssol_draw
(struct ssol_scene* scn,
struct ssol_camera* cam,
@@ -113,17 +115,27 @@ ssol_draw
ssol_write_pixels_T writer,
void* data)
{
- struct s3d_scene_view* view = NULL; /* TODO */
+ struct s3d_scene_view* view = NULL;
+ struct darray_byte* tiles = NULL;
int64_t mcode; /* Morton code of a tile */
float pix_sz[2];
size_t ntiles_x, ntiles_y, ntiles;
+ size_t i;
ATOMIC res = RES_OK;
- if(!scn || !cam || !writer || !data) {
+ if(!scn || !cam || !width || !height || !writer) {
res = RES_BAD_ARG;
goto error;
}
+ 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) {
+ const size_t sizeof_tile = TILE_SIZE * TILE_SIZE * sizeof(double[3]);
+ res = darray_byte_resize(tiles+i, sizeof_tile);
+ if(res != RES_OK) goto error;
+ }
+
ntiles_x = (width + (TILE_SIZE-1)/*ceil*/)/TILE_SIZE;
ntiles_y = (height+ (TILE_SIZE-1)/*ceil*/)/TILE_SIZE;
ntiles = round_up_pow2(MMAX(ntiles_x, ntiles_y));
@@ -132,10 +144,15 @@ ssol_draw
pix_sz[0] = 1.f / (float)width;
pix_sz[1] = 1.f / (float)height;
+ res = s3d_scene_view_create(scn->scn_rt, S3D_TRACE, &view);
+ if(res != RES_OK) goto error;
+
+ /* TODO parallelize the rendering */
FOR_EACH(mcode, 0, (int64_t)ntiles) {
size_t tile_org[2];
size_t tile_sz[2];
- double* pixels = NULL; /* TODO */
+ int ithread = 0;
+ double* pixels;
res_T res_local;
if(ATOMIC_GET(&res) != RES_OK) continue;
@@ -150,6 +167,8 @@ ssol_draw
tile_sz[0] = MMIN(TILE_SIZE, width - tile_org[0]);
tile_sz[1] = MMIN(TILE_SIZE, height- tile_org[1]);
+ pixels = (double*)darray_byte_data_get(tiles+ithread);
+
draw_tile(scn, view, cam, tile_org, tile_sz, pix_sz, pixels);
res_local = writer(data, tile_org, tile_sz, SSOL_PIXEL_DOUBLE3, pixels);
@@ -160,7 +179,9 @@ ssol_draw
}
exit:
+ if(view) S3D(scene_view_ref_put(view));
return (res_T)res;
error:
goto exit;
}
+