commit 4c39d9553901f6c4d9ab67c80f1adab7667e88ff
parent a59ae312ec435aac26f68d910a026f7e82ca9766
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 18 Apr 2024 15:26:22 +0200
External source API update
The source has been created from a structure grouping all its input
arguments, as for scene creation or calculation launch. But resources
such as media, interfaces or the radiative environment don't have the
same API: they are created from a shader that groups the resource's
(programmable) parameters, and a pointer to the user-side data. Since
the source is a resource, we modify its API to make it consistent with
that of other resources.
Diffstat:
7 files changed, 121 insertions(+), 92 deletions(-)
diff --git a/src/sdis.h b/src/sdis.h
@@ -188,8 +188,8 @@ typedef double /* [W/perpendicular m^2/sr] */
const double dir[3],
struct sdis_data* data);
-/* Input arguments of the sdis_spherical_source_create function */
-struct sdis_spherical_source_create_args {
+/* Parameters of an external spherical source */
+struct sdis_spherical_source_shader {
sdis_get_position_T position; /* [m/fp_to_meter] */
sdis_get_power_T power; /* Total power [W] */
@@ -203,10 +203,9 @@ struct sdis_spherical_source_create_args {
struct sdis_data* data; /* Data sent to the position functor */
double radius; /* [m] */
};
-#define SDIS_SPHERICAL_SOURCE_CREATE_ARGS_NULL__ {NULL, NULL, NULL, 0, 0}
-static const struct sdis_spherical_source_create_args
-SDIS_SPHERICAL_SOURCE_CREATE_ARGS_NULL =
- SDIS_SPHERICAL_SOURCE_CREATE_ARGS_NULL__;
+#define SDIS_SPHERICAL_SOURCE_SHADER_NULL__ {NULL, NULL, NULL, 0, 0}
+static const struct sdis_spherical_source_shader
+SDIS_SPHERICAL_SOURCE_SHADER_NULL = SDIS_SPHERICAL_SOURCE_SHADER_NULL__;
struct sdis_scene_find_closest_point_args {
double position[3]; /* Query position */
@@ -369,6 +368,7 @@ struct sdis_interface_shader {
static const struct sdis_interface_shader SDIS_INTERFACE_SHADER_NULL =
SDIS_INTERFACE_SHADER_NULL__;
+/* Parameters of a radiative environment */
struct sdis_radiative_env_shader {
sdis_radiative_ray_getter_T temperature; /* [K] */
sdis_radiative_ray_getter_T reference_temperature; /* [K] */
@@ -1144,10 +1144,16 @@ sdis_radiative_env_get_data
SDIS_API res_T
sdis_spherical_source_create
(struct sdis_device* dev,
- struct sdis_spherical_source_create_args* args,
+ const struct sdis_spherical_source_shader* shader,
+ struct sdis_data* data, /* Data sent to the shader. May be NULL */
struct sdis_source** source);
SDIS_API res_T
+sdis_spherical_source_get_shader
+ (const struct sdis_source* source,
+ struct sdis_spherical_source_shader* shader);
+
+SDIS_API res_T
sdis_source_ref_get
(struct sdis_source* source);
@@ -1155,17 +1161,9 @@ SDIS_API res_T
sdis_source_ref_put
(struct sdis_source* source);
-SDIS_API double /* [W] */
-sdis_source_get_power
- (struct sdis_source* source,
- const double time); /* [s] */
-
-/* Return the source radiance that is diffused in the environment */
-SDIS_API double /* [W/m^2/sr*] */
-sdis_source_get_diffuse_radiance
- (struct sdis_source* source,
- const double time, /* [s] */
- const double dir[3]);
+SDIS_API struct sdis_data*
+sdis_source_get_data
+ (struct sdis_source* source);
SDIS_API unsigned
sdis_source_get_id
diff --git a/src/sdis_source.c b/src/sdis_source.c
@@ -25,7 +25,8 @@
#include <star/ssp.h>
struct sdis_source {
- struct sdis_spherical_source_create_args spherical;
+ struct sdis_spherical_source_shader spherical;
+ struct sdis_data* data;
struct fid id; /* Unique identifier of the source */
struct sdis_device* dev;
@@ -36,27 +37,27 @@ struct sdis_source {
* Helper functions
******************************************************************************/
static res_T
-check_spherical_source_create_args
+check_spherical_source_shader
(struct sdis_device* dev,
const char* func_name,
- struct sdis_spherical_source_create_args* args)
+ const struct sdis_spherical_source_shader* shader)
{
ASSERT(func_name);
- if(!args) return RES_BAD_ARG;
+ if(!shader) return RES_BAD_ARG;
- if(!args->position) {
+ if(!shader->position) {
log_err(dev, "%s: the position functor is missing.\n", func_name);
return RES_BAD_ARG;
}
- if(!args->power) {
+ if(!shader->power) {
log_err(dev, "%s: the power functor is missing.\n", func_name);
return RES_BAD_ARG;
}
- if(args->radius < 0) {
+ if(shader->radius < 0) {
log_err(dev, "%s: invalid source radius '%g' m. It cannot be negative.\n",
- func_name, args->radius);
+ func_name, shader->radius);
return RES_BAD_ARG;
}
@@ -70,7 +71,7 @@ release_source(ref_T* ref)
struct sdis_source* src = CONTAINER_OF(ref, struct sdis_source, ref);
ASSERT(ref);
dev = src->dev;
- if(src->spherical.data) SDIS(data_ref_put(src->spherical.data));
+ if(src->data) SDIS(data_ref_put(src->data));
flist_name_del(&dev->source_names, src->id);
MEM_RM(dev->allocator, src);
SDIS(device_ref_put(dev));
@@ -82,14 +83,15 @@ release_source(ref_T* ref)
res_T
sdis_spherical_source_create
(struct sdis_device* dev,
- struct sdis_spherical_source_create_args* args,
+ const struct sdis_spherical_source_shader* shader,
+ struct sdis_data* data,
struct sdis_source** out_src)
{
struct sdis_source* src = NULL;
res_T res = RES_OK;
if(!dev || !out_src) { res = RES_BAD_ARG; goto error; }
- res = check_spherical_source_create_args(dev, FUNC_NAME, args);
+ res = check_spherical_source_shader(dev, FUNC_NAME, shader);
if(res != RES_OK) goto error;
src = MEM_CALLOC(dev->allocator, 1, sizeof(*src));
@@ -100,8 +102,9 @@ sdis_spherical_source_create
}
ref_init(&src->ref);
SDIS(device_ref_get(dev));
- if(args->data) SDIS(data_ref_get(args->data));
- src->spherical = *args;
+ if(data) SDIS(data_ref_get(data));
+ src->spherical = *shader;
+ src->data = data;
src->dev = dev;
src->id = flist_name_add(&dev->source_names);
flist_name_get(&dev->source_names, src->id)->mem = src;
@@ -115,6 +118,16 @@ error:
}
res_T
+sdis_spherical_source_get_shader
+ (const struct sdis_source* source,
+ struct sdis_spherical_source_shader* shader)
+{
+ if(!source || !shader) return RES_BAD_ARG;
+ *shader = source->spherical;
+ return RES_OK;
+}
+
+res_T
sdis_source_ref_get(struct sdis_source* src)
{
if(!src) return RES_BAD_ARG;
@@ -130,19 +143,11 @@ sdis_source_ref_put(struct sdis_source* src)
return RES_OK;
}
-double
-sdis_source_get_power(struct sdis_source* src, const double time /* [s] */)
+struct sdis_data*
+sdis_source_get_data(struct sdis_source* src)
{
- return source_get_power(src, time);
-}
-
-double
-sdis_source_get_diffuse_radiance
- (struct sdis_source* src,
- const double time, /* [s] */
- const double dir[3])
-{
- return source_get_diffuse_radiance(src, time, dir);
+ ASSERT(src);
+ return src->data;
}
unsigned
@@ -175,8 +180,8 @@ source_sample
ASSERT(src && rng && pos && sample);
/* Retrieve current source position, radius and power */
- src->spherical.position(time, src_pos, src->spherical.data);
- power = src->spherical.power(time, src->spherical.data);
+ src->spherical.position(time, src_pos, src->data);
+ power = src->spherical.power(time, src->data);
radius = src->spherical.radius;
if(power < 0) {
@@ -266,8 +271,8 @@ source_trace_to
}
/* Retrieve current source position and power */
- src->spherical.position(time, src_pos, src->spherical.data);
- power = src->spherical.power(time, src->spherical.data);
+ src->spherical.position(time, src_pos, src->data);
+ power = src->spherical.power(time, src->data);
if(power < 0) {
log_err(src->dev, "%s: invalid source power '%g' W. It cannot be negative.\n",
@@ -326,7 +331,7 @@ double /* [W] */
source_get_power(const struct sdis_source* src, const double time /* [s] */)
{
ASSERT(src);
- return src->spherical.power(time, src->spherical.data);
+ return src->spherical.power(time, src->data);
}
double /* [W/perpendicular m^2/sr] */
@@ -339,7 +344,7 @@ source_get_diffuse_radiance
if(src->spherical.diffuse_radiance == NULL) {
return 0;
} else {
- return src->spherical.diffuse_radiance(time, dir, src->spherical.data);
+ return src->spherical.diffuse_radiance(time, dir, src->data);
}
}
diff --git a/src/test_sdis_draw_external_flux.c b/src/test_sdis_draw_external_flux.c
@@ -205,15 +205,14 @@ source_get_diffuse_radiance
static struct sdis_source*
create_source(struct sdis_device* sdis)
{
- struct sdis_spherical_source_create_args args = SDIS_SPHERICAL_SOURCE_CREATE_ARGS_NULL;
+ struct sdis_spherical_source_shader shader = SDIS_SPHERICAL_SOURCE_SHADER_NULL;
struct sdis_source* source = NULL;
- args.position = source_get_position;
- args.power = source_get_power;
- args.diffuse_radiance = source_get_diffuse_radiance;
- args.data = NULL;
- args.radius = 3e-1; /* [m] */
- OK(sdis_spherical_source_create(sdis, &args, &source));
+ shader.position = source_get_position;
+ shader.power = source_get_power;
+ shader.diffuse_radiance = source_get_diffuse_radiance;
+ shader.radius = 3e-1; /* [m] */
+ OK(sdis_spherical_source_create(sdis, &shader, NULL, &source));
return source;
}
diff --git a/src/test_sdis_external_flux.c b/src/test_sdis_external_flux.c
@@ -282,14 +282,13 @@ source_get_power(const double time, struct sdis_data* data)
static struct sdis_source*
create_source(struct sdis_device* sdis)
{
- struct sdis_spherical_source_create_args args = SDIS_SPHERICAL_SOURCE_CREATE_ARGS_NULL;
+ struct sdis_spherical_source_shader shader = SDIS_SPHERICAL_SOURCE_SHADER_NULL;
struct sdis_source* src = NULL;
- args.position = source_get_position;
- args.power = source_get_power;
- args.data = NULL;
- args.radius = 6.5991756e8; /* [m] */
- OK(sdis_spherical_source_create(sdis, &args, &src));
+ shader.position = source_get_position;
+ shader.power = source_get_power;
+ shader.radius = 6.5991756e8; /* [m] */
+ OK(sdis_spherical_source_create(sdis, &shader, NULL, &src));
return src;
}
diff --git a/src/test_sdis_external_flux_with_diffuse_radiance.c b/src/test_sdis_external_flux_with_diffuse_radiance.c
@@ -222,8 +222,7 @@ source_get_diffuse_radiance
static struct sdis_source*
create_source(struct sdis_device* sdis, double** diffuse_radiance)
{
- struct sdis_spherical_source_create_args args =
- SDIS_SPHERICAL_SOURCE_CREATE_ARGS_NULL;
+ struct sdis_spherical_source_shader shader = SDIS_SPHERICAL_SOURCE_SHADER_NULL;
struct sdis_data* data = NULL;
struct sdis_source* src = NULL;
@@ -231,12 +230,11 @@ create_source(struct sdis_device* sdis, double** diffuse_radiance)
*diffuse_radiance = sdis_data_get(data);
**diffuse_radiance = 0;
- args.position = source_get_position;
- args.power = source_get_power;
- args.diffuse_radiance = source_get_diffuse_radiance;
- args.data = data;
- args.radius = SOURCE_RADIUS;
- OK(sdis_spherical_source_create(sdis, &args, &src));
+ shader.position = source_get_position;
+ shader.power = source_get_power;
+ shader.diffuse_radiance = source_get_diffuse_radiance;
+ shader.radius = SOURCE_RADIUS;
+ OK(sdis_spherical_source_create(sdis, &shader, data, &src));
OK(sdis_data_ref_put(data));
return src;
}
diff --git a/src/test_sdis_source.c b/src/test_sdis_source.c
@@ -38,29 +38,47 @@ spherical_source_get_power
return 10; /* [W] */
}
+static double
+spherical_source_get_diffuse_radiance
+ (const double time,
+ const double dir[3],
+ struct sdis_data* data)
+{
+ (void)time, (void)dir, (void)data;
+ return 50; /* [W/m^2/sr] */
+}
+
static void
check_spherical_source(struct sdis_device* dev)
{
- struct sdis_spherical_source_create_args args =
- SDIS_SPHERICAL_SOURCE_CREATE_ARGS_NULL;
+ struct sdis_spherical_source_shader shader = SDIS_SPHERICAL_SOURCE_SHADER_NULL;
+ struct sdis_spherical_source_shader shader2= SDIS_SPHERICAL_SOURCE_SHADER_NULL;
struct sdis_source* src = NULL;
struct sdis_source* src2 = NULL;
struct sdis_data* data = NULL;
+ const double dir[3] = {1,0,0};
/* Create a data to check its memory management */
OK(sdis_data_create(dev, sizeof(double[3]), ALIGNOF(double[3]), NULL, &data));
- args.position = spherical_source_get_position;
- args.power = spherical_source_get_power;
- args.data = data;
- args.radius = 1;
+ shader.position = spherical_source_get_position;
+ shader.power = spherical_source_get_power;
+ shader.radius = 1;
+ BA(sdis_spherical_source_create(NULL, &shader, data, &src));
+ BA(sdis_spherical_source_create(dev, NULL, data, &src));
+ BA(sdis_spherical_source_create(dev, &shader, data, NULL));
+ OK(sdis_spherical_source_create(dev, &shader, data, &src));
+
+ BA(sdis_spherical_source_get_shader(NULL, &shader2));
+ BA(sdis_spherical_source_get_shader(src, NULL));
+ OK(sdis_spherical_source_get_shader(src, &shader2));
- BA(sdis_spherical_source_create(NULL, &args, &src));
- BA(sdis_spherical_source_create(dev, NULL, &src));
- BA(sdis_spherical_source_create(dev, &args, NULL));
- OK(sdis_spherical_source_create(dev, &args, &src));
+ CHK(sdis_source_get_data(src) == data);
- CHK(sdis_source_get_power(src, INF) == 10);
+ CHK(shader2.position == shader.position);
+ CHK(shader2.power == shader.power);
+ CHK(shader2.diffuse_radiance == shader.diffuse_radiance);
+ CHK(shader2.power(INF, data) == 10);
BA(sdis_source_ref_get(NULL));
OK(sdis_source_ref_get(src));
@@ -70,18 +88,27 @@ check_spherical_source(struct sdis_device* dev)
OK(sdis_data_ref_put(data));
- args.data = NULL;
- OK(sdis_spherical_source_create(dev, &args, &src));
- OK(sdis_spherical_source_create(dev, &args, &src2));
+ OK(sdis_spherical_source_create(dev, &shader, NULL, &src));
+ OK(sdis_spherical_source_create(dev, &shader, NULL, &src2));
CHK(sdis_source_get_id(src) != sdis_source_get_id(src2));
+ CHK(sdis_source_get_data(src) == NULL);
OK(sdis_source_ref_put(src));
OK(sdis_source_ref_put(src2));
- args.position = NULL;
- BA(sdis_spherical_source_create(dev, &args, &src));
- args.position = spherical_source_get_position;
- args.power = NULL;
- BA(sdis_spherical_source_create(dev, &args, &src));
+ shader.position = NULL;
+ BA(sdis_spherical_source_create(dev, &shader, NULL, &src));
+ shader.position = spherical_source_get_position;
+ shader.power = NULL;
+ BA(sdis_spherical_source_create(dev, &shader, NULL, &src));
+ shader.power = spherical_source_get_power;
+ shader.diffuse_radiance = spherical_source_get_diffuse_radiance;
+ OK(sdis_spherical_source_create(dev, &shader, NULL, &src));
+
+ OK(sdis_spherical_source_get_shader(src, &shader2));
+ CHK(shader2.diffuse_radiance = spherical_source_get_diffuse_radiance);
+ CHK(shader2.diffuse_radiance(INF, dir, NULL) == 50);
+
+ OK(sdis_source_ref_put(src));
}
/*******************************************************************************
diff --git a/src/test_sdis_utils.c b/src/test_sdis_utils.c
@@ -89,15 +89,18 @@ accum_extflux
const struct sdis_green_external_flux_terms* terms,
void* ctx)
{
+ struct sdis_spherical_source_shader shader = SDIS_SPHERICAL_SOURCE_SHADER_NULL;
+ struct sdis_data* data = NULL;
double* extflux = ctx; /* External flux contribution [K] */
double power = 0; /* [W] */
double diffuse_radiance = 0; /* [W/m^2/sr] */
CHK(source && terms && ctx);
- power = sdis_source_get_power(source, terms->time);
- diffuse_radiance = sdis_source_get_diffuse_radiance
- (source, terms->time, terms->dir);
+ data = sdis_source_get_data(source);
+ OK(sdis_spherical_source_get_shader(source, &shader));
+ power = shader.power(terms->time, data);
+ diffuse_radiance = shader.diffuse_radiance(terms->time, terms->dir, data);
*extflux += terms->term_wrt_power * power;
*extflux += terms->term_wrt_diffuse_radiance * diffuse_radiance;