solstice-solver

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

commit 5a4725ec67bcfae858b47184399d9fc8abc58051
parent 3d59129c915f57456f2814f51b4dbc649629bb59
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue,  6 Dec 2016 15:59:41 +0100

Update the param_buffer API

Diffstat:
Msrc/ssol.h | 18++++++++----------
Msrc/ssol_param_buffer.c | 149+++++++++++++++++++------------------------------------------------------------
Msrc/test_ssol_material.c | 2+-
Msrc/test_ssol_param_buffer.c | 207++++++++++++++++++++++++++-----------------------------------------------------
4 files changed, 111 insertions(+), 265 deletions(-)

diff --git a/src/ssol.h b/src/ssol.h @@ -518,6 +518,7 @@ ssol_instance_get_id SSOL_API res_T ssol_param_buffer_create (struct ssol_device* dev, + const size_t capacity, struct ssol_param_buffer** buf); SSOL_API res_T @@ -528,19 +529,16 @@ SSOL_API res_T ssol_param_buffer_ref_put (struct ssol_param_buffer* buf); -SSOL_API res_T -ssol_param_buffer_set +SSOL_API void* +ssol_param_buffer_allocate (struct ssol_param_buffer* buf, - const char* name, - const size_t size, /* In Bytes */ - const size_t alignment, /* Must be a power of 2 in [1, 64] */ - const void* parameter); + const size_t size, + const size_t alignment); /* Power of 2 in [1, 64] */ -SSOL_API res_T +/* Retrieve the address of the first allocated parameter */ +SSOL_API void* ssol_param_buffer_get - (struct ssol_param_buffer* buf, - const char* name, - const void** parameter); + (struct ssol_param_buffer* buf); SSOL_API res_T ssol_param_buffer_clear diff --git a/src/ssol_param_buffer.c b/src/ssol_param_buffer.c @@ -17,7 +17,6 @@ #include "ssol_device_c.h" #include <rsys/dynamic_array.h> -#include <rsys/hash_table.h> #include <rsys/str.h> #define DEFAULT_ALIGNMENT 64 @@ -33,22 +32,10 @@ struct param { #define DARRAY_ALIGNMENT DEFAULT_ALIGNMENT #include <rsys/dynamic_array.h> -/* Define the hash table that maps the name of a parameter to its offset in the - * raw parameter buffer */ -#define HTABLE_NAME param -#define HTABLE_KEY struct str -#define HTABLE_DATA struct param -#define HTABLE_KEY_FUNCTOR_INIT str_init -#define HTABLE_KEY_FUNCTOR_RELEASE str_release -#define HTABLE_KEY_FUNCTOR_COPY str_copy -#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release -#define HTABLE_KEY_FUNCTOR_HASH str_hash -#define HTABLE_KEY_FUNCTOR_EQ str_eq -#include <rsys/hash_table.h> - struct ssol_param_buffer { - struct darray_byte buffer; - struct htable_param params; + char* pool; + size_t capacity; + size_t size; ref_T ref; struct ssol_device* dev; @@ -64,9 +51,8 @@ param_buffer_release(ref_T* ref) struct ssol_device* dev; ASSERT(ref); buf = CONTAINER_OF(ref, struct ssol_param_buffer, ref); - darray_byte_release(&buf->buffer); - htable_param_release(&buf->params); dev = buf->dev; + if(buf->pool) MEM_RM(dev->allocator, buf->pool); MEM_RM(dev->allocator, buf); SSOL(device_ref_put(dev)); } @@ -76,12 +62,14 @@ param_buffer_release(ref_T* ref) ******************************************************************************/ res_T ssol_param_buffer_create - (struct ssol_device* dev, struct ssol_param_buffer** out_buf) + (struct ssol_device* dev, + const size_t capacity, + struct ssol_param_buffer** out_buf) { struct ssol_param_buffer* buf = NULL; res_T res = RES_OK; - if(!dev || !out_buf) { + if(!dev || !capacity || !out_buf) { res = RES_BAD_ARG; goto error; } @@ -94,8 +82,13 @@ ssol_param_buffer_create SSOL(device_ref_get(dev)); buf->dev = dev; ref_init(&buf->ref); - htable_param_init(dev->allocator, &buf->params); - darray_byte_init(dev->allocator, &buf->buffer); + buf->capacity = capacity; + buf->size = 0; + buf->pool = MEM_ALLOC_ALIGNED(dev->allocator, capacity, DEFAULT_ALIGNMENT); + if(!buf->pool) { + res = RES_MEM_ERR; + goto error; + } exit: if(out_buf) *out_buf = buf; @@ -124,116 +117,44 @@ ssol_param_buffer_ref_put(struct ssol_param_buffer* buf) return RES_OK; } -res_T -ssol_param_buffer_set +void* +ssol_param_buffer_allocate (struct ssol_param_buffer* buf, - const char* name, const size_t size, /* In Bytes */ - const size_t alignment, /* Must be a power of 2 in [1, 64] */ - const void* parameter) + const size_t align) /* Must be a power of 2 in [1, 64] */ { - struct param* pparam; - char* dst; - size_t bufsz = SIZE_MAX; - struct str key; - res_T res = RES_OK; + size_t offset; + void* mem = NULL; - if(!buf || !name || name[0] == '\0' || !size || !IS_POW2(alignment) - || alignment > DEFAULT_ALIGNMENT || !parameter) { - return RES_BAD_ARG; - } + if(!buf || !size || !IS_POW2(align) || align > DEFAULT_ALIGNMENT) + goto error; - str_init(buf->dev->allocator, &key); - bufsz = darray_byte_size_get(&buf->buffer); - - res = str_set(&key, name); - if(res != RES_OK) goto error; - - pparam = htable_param_find(&buf->params, &key); - - if(pparam) { /* Update a previously set parameter */ - dst = darray_byte_data_get(&buf->buffer) + pparam->offset; - if(pparam->size < size || !IS_ALIGNED(dst, alignment)) { - log_error(buf->dev, -"%s: could not update the parameter `%s'. Incompatible size/alignment: \n" -"src size = %lu; src alignment = %lu; dst size = %lu; dst address = 0x%lx.\n", - FUNC_NAME, name, - (unsigned long)size, (unsigned long)alignment, - (unsigned long)pparam->size, (long)dst); - res = RES_BAD_ARG; - goto error; - } - if(MEM_AREA_OVERLAP(parameter, size, dst, size)) { - memmove(dst, parameter, size); - } else { - memcpy(dst, parameter, size); - } - } else { /* Setup a new parameter */ - struct param param; - - param.offset = ALIGN_SIZE(bufsz, alignment); - param.size = size; - - res = darray_byte_resize(&buf->buffer, param.offset + param.size); - if(res != RES_OK) goto error; - - dst = darray_byte_data_get(&buf->buffer) + param.offset; - ASSERT(IS_ALIGNED(dst, alignment)); - memcpy(dst, parameter, param.size); - - res = htable_param_set(&buf->params, &key, &param); - if(res != RES_OK) goto error; - } + offset = ALIGN_SIZE(buf->size, align); + if(offset + size > buf->capacity) goto error; + + mem = buf->pool + offset; + ASSERT(IS_ALIGNED(mem, align)); + buf->size = offset + size; exit: - str_release(&key); - return res; + return mem; error: - if(bufsz != SIZE_MAX) { - CHECK(darray_byte_resize(&buf->buffer, bufsz), RES_OK); - } + mem = NULL; goto exit; } -res_T -ssol_param_buffer_get - (struct ssol_param_buffer* buf, - const char* name, - const void** parameter) +void* +ssol_param_buffer_get(struct ssol_param_buffer* buf) { - struct param* pparam; - struct str key; - res_T res = RES_OK; - - - if(!buf || !name || !parameter) { - return RES_BAD_ARG; - } - - str_init(buf->dev->allocator, &key); - res = str_set(&key, name); - if(res != RES_OK) goto error; - - pparam = htable_param_find(&buf->params, &key); - if(!pparam) { - res = RES_BAD_ARG; - goto error; - } - *parameter = darray_byte_cdata_get(&buf->buffer) + pparam->offset; - -exit: - str_release(&key); - return res; -error: - goto exit; + ASSERT(buf); + return buf->size ? buf->pool : NULL; } res_T ssol_param_buffer_clear(struct ssol_param_buffer* buf) { if(!buf) return RES_BAD_ARG; - darray_byte_clear(&buf->buffer); - htable_param_clear(&buf->params); + buf->size = 0; return RES_OK; } diff --git a/src/test_ssol_material.c b/src/test_ssol_material.c @@ -50,7 +50,7 @@ main(int argc, char** argv) CHECK(ssol_material_ref_put(NULL), RES_BAD_ARG); CHECK(ssol_material_ref_put(material), RES_OK); - CHECK(ssol_param_buffer_create(dev, &pbuf), RES_OK); + CHECK(ssol_param_buffer_create(dev, 32, &pbuf), RES_OK); shader.normal = get_shader_normal; shader.reflectivity = get_shader_reflectivity; diff --git a/src/test_ssol_param_buffer.c b/src/test_ssol_param_buffer.c @@ -22,16 +22,17 @@ int main(int argc, char** argv) { + struct param { + char* name; + double d; + int i; + void* ptr; + }* param; struct mem_allocator allocator; struct ssol_device* dev; struct ssol_param_buffer* pbuf; - const char* str; - const void* p; - struct my_struct { int i; float f; char c; } my_struct; - double real; size_t sz, al; - int integer; - char character; + void* mem; (void)argc, (void)argv; CHECK(mem_init_proxy_allocator(&allocator, &mem_default_allocator), RES_OK); @@ -39,146 +40,67 @@ main(int argc, char** argv) CHECK(ssol_device_create (NULL, &allocator, SSOL_NTHREADS_DEFAULT, 0, &dev), RES_OK); - CHECK(ssol_param_buffer_create(NULL, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_create(dev, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_create(NULL, &pbuf), RES_BAD_ARG); - CHECK(ssol_param_buffer_create(dev, &pbuf), RES_OK); + CHECK(ssol_param_buffer_create(NULL, 0, NULL), RES_BAD_ARG); + CHECK(ssol_param_buffer_create(dev, 0, NULL), RES_BAD_ARG); + CHECK(ssol_param_buffer_create(NULL, 0, &pbuf), RES_BAD_ARG); + CHECK(ssol_param_buffer_create(dev, 0, &pbuf), RES_BAD_ARG); + CHECK(ssol_param_buffer_create(NULL, 1024, NULL), RES_BAD_ARG); + CHECK(ssol_param_buffer_create(dev, 1024, NULL), RES_BAD_ARG); + CHECK(ssol_param_buffer_create(NULL, 1024, &pbuf), RES_BAD_ARG); + CHECK(ssol_param_buffer_create(dev, 1024, &pbuf), RES_OK); + + CHECK(ssol_param_buffer_get(pbuf), NULL); sz = sizeof(const char*); al = ALIGNOF(const char*); - str = __FILE__; - CHECK(ssol_param_buffer_set(NULL, NULL, 0, 0, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(pbuf, NULL, 0, 0, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(NULL, "file", 0, 0, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(pbuf, "file", 0, 0, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(NULL, NULL, sz, 0, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(pbuf, NULL, sz, 0, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(NULL, "file", sz, 0, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(pbuf, "file", sz, 0, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(NULL, NULL, 0, al, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(pbuf, NULL, 0, al, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(NULL, "file", 0, al, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(pbuf, "file", 0, al, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(NULL, NULL, sz, al, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(pbuf, NULL, sz, al, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(NULL, "file", sz, al, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(pbuf, "file", sz, al, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(NULL, NULL, 0, 0, &str), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(pbuf, NULL, 0, 0, &str), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(NULL, "file", 0, 0, &str), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(pbuf, "file", 0, 0, &str), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(NULL, NULL, sz, 0, &str), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(pbuf, NULL, sz, 0, &str), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(NULL, "file", sz, 0, &str), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(pbuf, "file", sz, 0, &str), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(NULL, NULL, 0, al, &str), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(pbuf, NULL, 0, al, &str), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(NULL, "file", 0, al, &str), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(pbuf, "file", 0, al, &str), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(NULL, NULL, sz, al, &str), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(pbuf, NULL, sz, al, &str), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(NULL, "file", sz, al, &str), RES_BAD_ARG); - CHECK(ssol_param_buffer_set(pbuf, "file", sz, al, &str), RES_OK); - - CHECK(ssol_param_buffer_get(NULL, NULL, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_get(pbuf, NULL, NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_get(NULL, "file", NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_get(pbuf, "file", NULL), RES_BAD_ARG); - CHECK(ssol_param_buffer_get(NULL, NULL, &p), RES_BAD_ARG); - CHECK(ssol_param_buffer_get(pbuf, NULL, &p), RES_BAD_ARG); - CHECK(ssol_param_buffer_get(NULL, "file", &p), RES_BAD_ARG); - CHECK(ssol_param_buffer_get(pbuf, "file", &p), RES_OK); - NCHECK(p, NULL); - CHECK(IS_ALIGNED(p, al), 1); - CHECK(strcmp(*(const char**)p, __FILE__), 0); - CHECK(ssol_param_buffer_get(pbuf, "none", &p), RES_BAD_ARG); - - str = "Foo"; - CHECK(ssol_param_buffer_set(pbuf, "file", sz, al, &str), RES_OK); - CHECK(ssol_param_buffer_get(pbuf, "file", &p), RES_OK); - NCHECK(p, NULL); - CHECK(IS_ALIGNED(p, al), 1); - CHECK(strcmp(*(const char**)p, "Foo"), 0); + CHECK(mem = ssol_param_buffer_allocate(NULL, 0, 0), NULL); + CHECK(mem = ssol_param_buffer_allocate(pbuf, 0, 0), NULL); + CHECK(mem = ssol_param_buffer_allocate(NULL, sz, 0), NULL); + CHECK(mem = ssol_param_buffer_allocate(pbuf, sz, 0), NULL); + CHECK(mem = ssol_param_buffer_allocate(NULL, 0, al), NULL); + CHECK(mem = ssol_param_buffer_allocate(pbuf, 0, al), NULL); + CHECK(mem = ssol_param_buffer_allocate(NULL, sz, al), NULL); + NCHECK(mem = ssol_param_buffer_allocate(pbuf, sz, al), NULL); + + *(const char**)mem = __FILE__; + CHECK(*(const char**)ssol_param_buffer_get(pbuf), __FILE__); + + *(const char**)mem = FUNC_NAME; + CHECK(*(const char**)ssol_param_buffer_get(pbuf), FUNC_NAME); CHECK(ssol_param_buffer_clear(NULL), RES_BAD_ARG); CHECK(ssol_param_buffer_clear(pbuf), RES_OK); - CHECK(ssol_param_buffer_get(pbuf, "file", &p), RES_BAD_ARG); - - str = "Hello"; - sz = strlen(str) + 1/*NULL char*/; - al = 8; - CHECK(ssol_param_buffer_set(pbuf, "hello", sz, al, str), RES_OK); - CHECK(ssol_param_buffer_get(pbuf, "hello", &p), RES_OK); - str = "world!"; - sz = strlen(str) + 1/*NULL char*/; - CHECK(strcmp((const char*)p, "Hello"), 0); - CHECK(ssol_param_buffer_set(pbuf, "hello", sz, al, str), RES_BAD_ARG); - str = "world"; - sz = strlen(str) + 1/*NULL char*/; - CHECK(ssol_param_buffer_set(pbuf, "hello", sz, al, str), RES_OK); - CHECK(ssol_param_buffer_get(pbuf, "hello", &p), RES_OK); - CHECK(strcmp((const char*)p, "world"), 0); - - sz = sizeof(real); - real = PI; - CHECK(ssol_param_buffer_set(pbuf, "PI", sz, 8, &real), RES_OK); - real = 1.0/PI; - CHECK(ssol_param_buffer_set(pbuf, "1/PI", sz, 64, &real), RES_OK); - real = 1.0/(2.0*PI); - CHECK(ssol_param_buffer_set(pbuf, "1/2PI", sz, 32, &real), RES_OK); - real = 1/(4.0*PI); - CHECK(ssol_param_buffer_set(pbuf, "1/4PI", sz, 16, &real), RES_OK); - str = "Hello world!"; - sz = strlen(str) + 1/*NULL char*/; - CHECK(ssol_param_buffer_set(pbuf, "Hello", sz, 8, str), RES_OK); - integer = INT_MAX; - sz = sizeof(integer); - CHECK(ssol_param_buffer_set(pbuf, "INT_MAX", sz, 64, &integer), RES_OK); - FOR_EACH(character, 'a', 'Z') { - char name[2]; - name[0] = character; - name[1] = '\0'; - CHECK(ssol_param_buffer_set(pbuf, name, 1, 32, &character), RES_OK); - } - - my_struct.i = INT_MAX; - my_struct.f = (float)PI; - my_struct.c = 'X'; - sz = sizeof(my_struct); - al = ALIGNOF(struct my_struct); - CHECK(ssol_param_buffer_set(pbuf, "my_struct", sz, al, &my_struct), RES_OK); - - CHECK(ssol_param_buffer_get(pbuf, "hello", &p), RES_OK); - CHECK(strcmp(p, "world"), 0); - CHECK(ssol_param_buffer_get(pbuf, "Hello", &p), RES_OK); - CHECK(strcmp(p, "Hello world!"), 0); - CHECK(ssol_param_buffer_get(pbuf, "PI", &p), RES_OK); - CHECK(*(double*)p, PI); - CHECK(IS_ALIGNED(p, 8), 1); - CHECK(ssol_param_buffer_get(pbuf, "1/PI", &p), RES_OK); - CHECK(*(double*)p, 1/PI); - CHECK(IS_ALIGNED(p, 64), 1); - CHECK(ssol_param_buffer_get(pbuf, "1/2PI", &p), RES_OK); - CHECK(*(double*)p, 1/(2*PI)); - CHECK(IS_ALIGNED(p, 32), 1); - CHECK(ssol_param_buffer_get(pbuf, "1/4PI", &p), RES_OK); - CHECK(*(double*)p, 1/(4*PI)); - CHECK(IS_ALIGNED(p, 16), 1); - - FOR_EACH(character, 'a', 'Z') { - char name[2]; - name[0] = character; - name[1] = '\0'; - CHECK(ssol_param_buffer_get(pbuf, name, &p), RES_OK); - CHECK(*(char*)p, character); - CHECK(IS_ALIGNED(p, 32), 1); - } - - CHECK(ssol_param_buffer_get(pbuf, "my_struct", &p), RES_OK); - CHECK(((struct my_struct*)p)->i, INT_MAX); - CHECK(((struct my_struct*)p)->f, (float)PI); - CHECK(((struct my_struct*)p)->c, 'X'); - CHECK(IS_ALIGNED(p, ALIGNOF(struct my_struct)), 1); + CHECK(ssol_param_buffer_get(pbuf), NULL); + + sz = strlen("Foo") + 1; + al = 4; + NCHECK(mem = ssol_param_buffer_allocate(pbuf, sz, al), NULL); + strcpy(mem, "Foo"); + CHECK(strcmp(ssol_param_buffer_get(pbuf), "Foo"), 0); + strcpy(mem, "Bar"); + CHECK(strcmp(ssol_param_buffer_get(pbuf), "Bar"), 0); + CHECK(IS_ALIGNED(ssol_param_buffer_get(pbuf), al), 1); + + CHECK(ssol_param_buffer_clear(pbuf), RES_OK); + + sz = sizeof(struct param); + al = ALIGNOF(struct param); + NCHECK(param = ssol_param_buffer_allocate(pbuf, sz, al), NULL); + NCHECK(param->name = ssol_param_buffer_allocate(pbuf, 7, 64), NULL); + strcpy(param->name, "0123456"); + NCHECK(param->ptr = ssol_param_buffer_allocate(pbuf, 4, 16), NULL); + param->d = PI; + param->i = -123; + strcpy(param->ptr, "abc"); + + NCHECK(param = ssol_param_buffer_get(pbuf), NULL); + CHECK(IS_ALIGNED(param, ALIGNOF(struct param)), 1); + CHECK(IS_ALIGNED(param->name, 64), 1); + CHECK(IS_ALIGNED(param->ptr, 16), 1); + CHECK(param->d, PI); + CHECK(param->i, -123); + CHECK(strcmp(param->name, "0123456"), 0); + CHECK(strcmp(param->ptr, "abc"), 0); CHECK(ssol_param_buffer_ref_get(NULL), RES_BAD_ARG); CHECK(ssol_param_buffer_ref_get(pbuf), RES_OK); @@ -186,6 +108,11 @@ main(int argc, char** argv) CHECK(ssol_param_buffer_ref_put(pbuf), RES_OK); CHECK(ssol_param_buffer_ref_put(pbuf), RES_OK); + CHECK(ssol_param_buffer_create(dev, 8, &pbuf), RES_OK); + NCHECK(mem = ssol_param_buffer_allocate(pbuf, 2, 1), NULL); + CHECK(mem = ssol_param_buffer_allocate(pbuf, 1, 16), NULL); + + CHECK(ssol_param_buffer_ref_put(pbuf), RES_OK); CHECK(ssol_device_ref_put(dev), RES_OK); check_memory_allocator(&allocator);