commit d16bb582620c075a9dfab21984e55c3e353fc9d5
parent c44a28638b5f67be4a4c4ca47f356f2fd195b2b8
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 30 Sep 2022 11:32:37 +0200
Pre-allocate the list of BSDF for each material
Diffstat:
| M | src/rngrd.c | | | 59 | ++++++++++++++++++++++++++++++++++++++++++++++++++--------- |
| M | src/rngrd_c.h | | | 51 | ++++++++++++++++++++++++++++++++++++++++++++------- |
| M | src/rngrd_properties.c | | | 225 | +++++++++++++++++++++++++++++++++++++++++++++++++------------------------------ |
3 files changed, 234 insertions(+), 101 deletions(-)
diff --git a/src/rngrd.c b/src/rngrd.c
@@ -26,6 +26,7 @@
#include <star/s3d.h>
#include <star/sbuf.h>
+#include <star/ssf.h>
#include <rsys/cstr.h>
#include <rsys/mem_allocator.h>
@@ -194,35 +195,75 @@ error:
* Local functions
******************************************************************************/
res_T
-mtl_init(struct mem_allocator* allocator, struct mrumtl** mtl)
+bsdf_init(struct mem_allocator* allocator, struct ssf_bsdf** bsdf)
{
+ ASSERT(bsdf);
(void)allocator;
- *mtl = NULL;
+ *bsdf = NULL;
return RES_OK;
}
void
-mtl_release(struct mrumtl** mtl)
+bsdf_release(struct ssf_bsdf** bsdf)
{
- if(*mtl) MRUMTL(ref_put(*mtl));
+ ASSERT(bsdf);
+ if(*bsdf) SSF(bsdf_ref_put(*bsdf));
}
res_T
-mtl_copy(struct mrumtl** dst, struct mrumtl* const* src)
+bsdf_copy(struct ssf_bsdf** dst, struct ssf_bsdf* const* src)
{
ASSERT(dst && src);
- if(*dst) MRUMTL(ref_put(*dst));
+ if(*dst) SSF(bsdf_ref_put(*dst));
*dst = *src;
- if(*dst) MRUMTL(ref_get(*dst));
+ if(*dst) SSF(bsdf_ref_get(*dst));
return RES_OK;
}
res_T
-mtl_copy_and_release(struct mrumtl** dst, struct mrumtl** src)
+bsdf_copy_and_release(struct ssf_bsdf** dst, struct ssf_bsdf** src)
{
ASSERT(dst && src);
- if(*dst) MRUMTL(ref_put(*dst));
+ if(*dst) SSF(bsdf_ref_put(*dst));
*dst = *src;
*src = NULL;
return RES_OK;
}
+
+
+res_T
+mtl_init(struct mem_allocator* allocator, struct mtl* mtl)
+{
+ ASSERT(mtl);
+ mtl->mrumtl = NULL;
+ darray_bsdf_init(allocator, &mtl->bsdf_lst);
+ return RES_OK;
+}
+
+void
+mtl_release(struct mtl* mtl)
+{
+ ASSERT(mtl);
+ if(mtl->mrumtl) MRUMTL(ref_put(mtl->mrumtl));
+ darray_bsdf_release(&mtl->bsdf_lst);
+}
+
+res_T
+mtl_copy(struct mtl* dst, const struct mtl* src)
+{
+ ASSERT(dst && src);
+ if(dst->mrumtl) MRUMTL(ref_put(dst->mrumtl));
+ dst->mrumtl = src->mrumtl;
+ if(dst->mrumtl) MRUMTL(ref_get(dst->mrumtl));
+ return darray_bsdf_copy(&dst->bsdf_lst, &src->bsdf_lst);;
+}
+
+res_T
+mtl_copy_and_release(struct mtl* dst, struct mtl* src)
+{
+ ASSERT(dst && src);
+ if(dst->mrumtl) MRUMTL(ref_put(dst->mrumtl));
+ dst->mrumtl = src->mrumtl;
+ src->mrumtl = NULL;
+ return darray_bsdf_copy_and_release(&dst->bsdf_lst, &src->bsdf_lst);
+}
diff --git a/src/rngrd_c.h b/src/rngrd_c.h
@@ -28,32 +28,69 @@
struct rngrd_create_args;
struct mrumtl;
+struct ssf_bsdf;
+
+/*******************************************************************************
+ * BSDF
+ ******************************************************************************/
+extern LOCAL_SYM res_T
+bsdf_init
+ (struct mem_allocator* allocator,
+ struct ssf_bsdf** bsdf);
+
+extern LOCAL_SYM void
+bsdf_release
+ (struct ssf_bsdf** bsdf);
+
+extern LOCAL_SYM res_T
+bsdf_copy
+ (struct ssf_bsdf** dst,
+ struct ssf_bsdf* const* src);
+
+extern LOCAL_SYM res_T
+bsdf_copy_and_release
+ (struct ssf_bsdf** dst,
+ struct ssf_bsdf** src);
+
+/* Generate the dynamic array of BSDFs */
+#define DARRAY_NAME bsdf
+#define DARRAY_DATA struct ssf_bsdf*
+#define DARRAY_FUNCTOR_INIT bsdf_init
+#define DARRAY_FUNCTOR_RELEASE bsdf_release
+#define DARRAY_FUNCTOR_COPY bsdf_copy
+#define DARRAY_FUNCTOR_COPY_AND_RELEASE bsdf_copy_and_release
+#include <rsys/dynamic_array.h>
/*******************************************************************************
* Material
******************************************************************************/
+struct mtl {
+ struct mrumtl* mrumtl;
+ struct darray_bsdf bsdf_lst;
+};
+
extern LOCAL_SYM res_T
mtl_init
(struct mem_allocator* allocator,
- struct mrumtl** mtl);
+ struct mtl* mtl);
extern LOCAL_SYM void
mtl_release
- (struct mrumtl** mtl);
+ (struct mtl* mtl);
extern LOCAL_SYM res_T
mtl_copy
- (struct mrumtl** dst,
- struct mrumtl* const* src);
+ (struct mtl* dst,
+ const struct mtl* src);
extern LOCAL_SYM res_T
mtl_copy_and_release
- (struct mrumtl** dst,
- struct mrumtl** src);
+ (struct mtl* dst,
+ struct mtl* src);
/* Generate the dynamic array of materials */
#define DARRAY_NAME mtl
-#define DARRAY_DATA struct mrumtl*
+#define DARRAY_DATA struct mtl
#define DARRAY_FUNCTOR_INIT mtl_init
#define DARRAY_FUNCTOR_RELEASE mtl_release
#define DARRAY_FUNCTOR_COPY mtl_copy
diff --git a/src/rngrd_properties.c b/src/rngrd_properties.c
@@ -91,6 +91,129 @@ check_sbuf_desc
}
static res_T
+create_bsdf_diffuse
+ (struct rngrd* ground,
+ const struct mrumtl_brdf_lambertian* lambertian,
+ struct ssf_bsdf** out_bsdf)
+{
+ struct ssf_bsdf* bsdf = NULL;
+ struct mem_allocator* allocator = NULL;
+ res_T res = RES_OK;
+ ASSERT(ground && lambertian && out_bsdf);
+
+ allocator = ground->allocator;
+
+ res = ssf_bsdf_create(allocator, &ssf_lambertian_reflection, &bsdf);
+ if(res != RES_OK) goto error;
+ res = ssf_lambertian_reflection_setup(bsdf, lambertian->reflectivity);
+ if(res != RES_OK) goto error;
+
+exit:
+ *out_bsdf = bsdf;
+ return res;
+error:
+ if(bsdf) { SSF(bsdf_ref_put(bsdf)); bsdf = NULL; }
+ goto exit;
+}
+
+static res_T
+create_bsdf_specular
+ (struct rngrd* ground,
+ const struct mrumtl_brdf_specular* specular,
+ struct ssf_bsdf** out_bsdf)
+{
+ struct ssf_bsdf* bsdf = NULL;
+ struct ssf_fresnel* fresnel = NULL;
+ struct mem_allocator* allocator = NULL;
+ res_T res = RES_OK;
+ ASSERT(ground && specular && out_bsdf);
+
+ allocator = ground->allocator;
+
+ res = ssf_bsdf_create(allocator, &ssf_specular_reflection, &bsdf);
+ if(res != RES_OK) goto error;
+ res = ssf_fresnel_create(allocator, &ssf_fresnel_constant, &fresnel);
+ if(res != RES_OK) goto error;
+ res = ssf_fresnel_constant_setup(fresnel, specular->reflectivity);
+ if(res != RES_OK) goto error;
+ res = ssf_specular_reflection_setup(bsdf, fresnel);
+ if(res != RES_OK) goto error;
+
+exit:
+ if(fresnel) SSF(fresnel_ref_put(fresnel));
+ *out_bsdf = bsdf;
+ return res;
+error:
+ if(bsdf) { SSF(bsdf_ref_put(bsdf)); bsdf = NULL; }
+ goto exit;
+}
+
+static INLINE res_T
+create_bsdf
+ (struct rngrd* ground,
+ const struct mrumtl_brdf* brdf,
+ struct ssf_bsdf** out_bsdf)
+{
+ struct mrumtl_brdf_lambertian lambertian;
+ struct mrumtl_brdf_specular specular;
+ res_T res = RES_OK;
+ ASSERT(ground && brdf && out_bsdf);
+
+ switch(mrumtl_brdf_get_type(brdf)) {
+ case MRUMTL_BRDF_LAMBERTIAN:
+ MRUMTL(brdf_get_lambertian(brdf, &lambertian));
+ res = create_bsdf_diffuse(ground, &lambertian, out_bsdf);
+ if(res != RES_OK) goto error;
+ break;
+ case MRUMTL_BRDF_SPECULAR:
+ MRUMTL(brdf_get_specular(brdf, &specular));
+ res = create_bsdf_specular(ground, &specular, out_bsdf);
+ if(res != RES_OK) goto error;
+ break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+mtl_create_bsdf_list
+ (struct rngrd* ground,
+ const char* filename,
+ struct mtl* mtl)
+{
+ size_t nbsdfs = 0;
+ size_t ibsdf = 0;
+ res_T res = RES_OK;
+ ASSERT(ground && filename && mtl);
+
+ /* Reserve memory space for the list of BSDFs */
+ nbsdfs = mrumtl_get_brdfs_count(mtl->mrumtl);
+ res = darray_bsdf_resize(&mtl->bsdf_lst, nbsdfs);
+ if(res != RES_OK) goto error;
+
+ FOR_EACH(ibsdf, 0, nbsdfs) {
+ const struct mrumtl_brdf* brdf = mrumtl_get_brdf(mtl->mrumtl, ibsdf);
+ struct ssf_bsdf** bsdf = darray_bsdf_data_get(&mtl->bsdf_lst) + ibsdf;
+
+ res = create_bsdf(ground, brdf, bsdf);
+ if(res != RES_OK) goto error;
+ }
+
+exit:
+ return res;
+
+error:
+ log_err(ground, "%s: error creating the list of BSDFs -- %s\n",
+ filename, res_to_cstr(res));
+ darray_bsdf_clear(&mtl->bsdf_lst);
+ goto exit;
+}
+
+static res_T
load_mtl(struct rngrd* ground, const char* filename, struct mrumtl** out_mtl)
{
struct mrumtl_create_args args = MRUMTL_CREATE_ARGS_DEFAULT;
@@ -126,6 +249,7 @@ load_mtllst(struct rngrd* ground, const struct rngrd_create_args* args)
size_t imtl, nmtls;
res_T res = RES_OK;
+ /* Create loader of material paths */
rnsl_args.logger = ground->logger;
rnsl_args.allocator = ground->allocator;
rnsl_args.verbose = ground->verbose;
@@ -136,9 +260,11 @@ load_mtllst(struct rngrd* ground, const struct rngrd_create_args* args)
goto error;
}
+ /* Load the list of material paths */
res = rnsl_load(rnsl, args->mtllst_filename);
if(res != RES_OK) goto error;
+ /* Reserve memory space for the list of materials */
nmtls = rnsl_get_strings_count(rnsl);
res = darray_mtl_resize(&ground->mtls, nmtls);
if(res != RES_OK) {
@@ -147,10 +273,14 @@ load_mtllst(struct rngrd* ground, const struct rngrd_create_args* args)
goto error;
}
+ /* Load the list of materials and create their associated BSDFs */
FOR_EACH(imtl, 0, nmtls) {
- struct mrumtl** mtl = darray_mtl_data_get(&ground->mtls)+imtl;
+ struct mtl* mtl = darray_mtl_data_get(&ground->mtls)+imtl;
const char* filename = rnsl_get_string(rnsl, imtl);
- res = load_mtl(ground, filename, mtl);
+
+ res = load_mtl(ground, filename, &mtl->mrumtl);
+ if(res != RES_OK) goto error;
+ res = mtl_create_bsdf_list(ground, filename, mtl);
if(res != RES_OK) goto error;
}
@@ -162,66 +292,6 @@ error:
goto exit;
}
-static res_T
-create_bsdf_diffuse
- (struct rngrd* ground,
- const struct mrumtl_brdf_lambertian* lambertian,
- struct ssf_bsdf** out_bsdf)
-{
- struct ssf_bsdf* bsdf = NULL;
- struct mem_allocator* allocator = NULL;
- res_T res = RES_OK;
- ASSERT(ground && lambertian && out_bsdf);
-
- /* TODO speed up allocation by using a [per thread] fifo allocator */
- allocator = ground->allocator;
-
- res = ssf_bsdf_create(allocator, &ssf_lambertian_reflection, &bsdf);
- if(res != RES_OK) goto error;
- res = ssf_lambertian_reflection_setup(bsdf, lambertian->reflectivity);
- if(res != RES_OK) goto error;
-
-exit:
- *out_bsdf = bsdf;
- return res;
-error:
- if(bsdf) { SSF(bsdf_ref_put(bsdf)); bsdf = NULL; }
- goto exit;
-}
-
-static res_T
-create_bsdf_specular
- (struct rngrd* ground,
- const struct mrumtl_brdf_specular* specular,
- struct ssf_bsdf** out_bsdf)
-{
- struct ssf_bsdf* bsdf = NULL;
- struct ssf_fresnel* fresnel = NULL;
- struct mem_allocator* allocator = NULL;
- res_T res = RES_OK;
- ASSERT(ground && specular && out_bsdf);
-
- /* TODO speed up allocation by using a [per thread] fifo allocator */
- allocator = ground->allocator;
-
- res = ssf_bsdf_create(allocator, &ssf_specular_reflection, &bsdf);
- if(res != RES_OK) goto error;
- res = ssf_fresnel_create(allocator, &ssf_fresnel_constant, &fresnel);
- if(res != RES_OK) goto error;
- res = ssf_fresnel_constant_setup(fresnel, specular->reflectivity);
- if(res != RES_OK) goto error;
- res = ssf_specular_reflection_setup(bsdf, fresnel);
- if(res != RES_OK) goto error;
-
-exit:
- if(fresnel) SSF(fresnel_ref_put(fresnel));
- *out_bsdf = bsdf;
- return res;
-error:
- if(bsdf) { SSF(bsdf_ref_put(bsdf)); bsdf = NULL; }
- goto exit;
-}
-
/*******************************************************************************
* Exported functions
******************************************************************************/
@@ -231,13 +301,10 @@ rngrd_create_bsdf
const struct rngrd_create_bsdf_args* args,
struct ssf_bsdf** out_bsdf)
{
- struct mrumtl_brdf_lambertian lambertian;
- struct mrumtl_brdf_specular specular;
const struct ALIGN(8) { uint32_t mtl_id; float temperature; }* item = NULL;
- const struct mrumtl_brdf* brdf = NULL;
- const struct mrumtl* mtl = NULL;
+ struct mtl* mtl = NULL;
struct ssf_bsdf* bsdf = NULL;
- size_t ibrdf;
+ size_t ibsdf;
struct sbuf_desc desc;
res_T res = RES_OK;
@@ -252,27 +319,15 @@ rngrd_create_bsdf
/* Retrieve the spectrally varying material of the primitive */
ASSERT(item->mtl_id < darray_mtl_size_get(&ground->mtls));
- mtl = darray_mtl_cdata_get(&ground->mtls)[item->mtl_id];
+ mtl = darray_mtl_data_get(&ground->mtls)+item->mtl_id;
- /* Get the BRDF based on the input wavelength */
- res = mrumtl_fetch_brdf(mtl, args->wavelength, args->r, &ibrdf);
+ /* Get the BSDF based on the input wavelength */
+ res = mrumtl_fetch_brdf(mtl->mrumtl, args->wavelength, args->r, &ibsdf);
if(res != RES_OK) goto error;
- brdf = mrumtl_get_brdf(mtl, ibrdf);
- /* Create the scattering function */
- switch(mrumtl_brdf_get_type(brdf)) {
- case MRUMTL_BRDF_LAMBERTIAN:
- MRUMTL(brdf_get_lambertian(brdf, &lambertian));
- res = create_bsdf_diffuse(ground, &lambertian, &bsdf);
- if(res != RES_OK) goto error;
- break;
- case MRUMTL_BRDF_SPECULAR:
- MRUMTL(brdf_get_specular(brdf, &specular));
- res = create_bsdf_specular(ground, &specular, &bsdf);
- if(res != RES_OK) goto error;
- break;
- default: FATAL("Unreachable code.\n"); break;
- }
+ bsdf = darray_bsdf_data_get(&mtl->bsdf_lst)[ibsdf];
+ ASSERT(bsdf);
+ SSF(bsdf_ref_get(bsdf));
exit:
if(out_bsdf) *out_bsdf = bsdf;