diff --git a/src/venus/vkr_common.h b/src/venus/vkr_common.h index f45f207..016c73a 100644 --- a/src/venus/vkr_common.h +++ b/src/venus/vkr_common.h @@ -96,40 +96,6 @@ vkr_context_remove_objects(ctx, &free_list); \ } while (0) -#define CREATE_PIPELINES(vk_cmd) \ - do { \ - struct vkr_device *dev = (struct vkr_device *)args->device; \ - \ - struct object_array arr; \ - if (!object_array_init(ctx, &arr, args->createInfoCount, VK_OBJECT_TYPE_PIPELINE, \ - sizeof(struct vkr_pipeline), sizeof(VkPipeline), \ - args->pPipelines)) { \ - args->ret = VK_ERROR_OUT_OF_HOST_MEMORY; \ - return; \ - } \ - \ - vn_replace_##vk_cmd##_args_handle(args); \ - args->ret = vk_cmd(args->device, args->pipelineCache, args->createInfoCount, \ - args->pCreateInfos, NULL, arr.handle_storage); \ - if (args->ret != VK_SUCCESS) { \ - object_array_fini(&arr); \ - return; \ - } \ - \ - for (uint32_t i = 0; i < arr.count; i++) { \ - struct vkr_pipeline *pipeline = arr.objects[i]; \ - \ - pipeline->base.handle.pipeline = ((VkPipeline *)arr.handle_storage)[i]; \ - \ - list_add(&pipeline->base.track_head, &dev->objects); \ - \ - vkr_device_add_object(ctx, &pipeline->base); \ - } \ - \ - arr.objects_stolen = true; \ - object_array_fini(&arr); \ - } while (0) - struct vkr_context; struct vkr_instance; struct vkr_physical_device; diff --git a/src/venus/vkr_device_object.py b/src/venus/vkr_device_object.py index fb70a3b..98805de 100644 --- a/src/venus/vkr_device_object.py +++ b/src/venus/vkr_device_object.py @@ -39,6 +39,23 @@ VkResult vkr_{create_func_name}_create_driver_handles( }} ''' +PIPELINE_OBJECT_CREATE_DRIVER_HANDLES_TEMPL = ''' +/* create an array of driver {vk_type}s and update the object_array */ +static inline VkResult +vkr_{create_func_name}_create_driver_handles( + UNUSED struct vkr_context *ctx, + struct vn_command_{create_cmd} *args, + struct object_array *arr) +{{ + /* handles in args are replaced */ + vn_replace_{create_cmd}_args_handle(args); + args->ret = {create_cmd}(args->device, args->{create_cache}, + args->{create_count}, args->{create_info}, NULL, + arr->handle_storage); + return args->ret; +}} +''' + SIMPLE_OBJECT_DESTROY_DRIVER_HANDLE_TEMPL = ''' /* destroy a driver {vk_type} */ static inline void @@ -81,7 +98,7 @@ vkr_{destroy_func_name}_destroy_driver_handles( PIPELINE_OBJECT_DESTROY_DRIVER_HANDLE_TEMPL = SIMPLE_OBJECT_DESTROY_DRIVER_HANDLE_TEMPL -POOL_OBJECT_INIT_ARRAY_TEMPL = ''' +COMMON_OBJECT_INIT_ARRAY_TEMPL = ''' /* initialize an object_array for vkr_{vkr_type}s */ static inline VkResult vkr_{create_func_name}_init_array( @@ -99,6 +116,9 @@ vkr_{create_func_name}_init_array( }} ''' +POOL_OBJECT_INIT_ARRAY_TEMPL = COMMON_OBJECT_INIT_ARRAY_TEMPL +PIPELINE_OBJECT_INIT_ARRAY_TEMPL = COMMON_OBJECT_INIT_ARRAY_TEMPL + SIMPLE_OBJECT_CREATE_TEMPL = ''' /* create a vkr_{vkr_type} */ static inline struct vkr_{vkr_type} * @@ -123,7 +143,7 @@ vkr_{create_func_name}_create( }} ''' -POOL_OBJECT_CREATE_ARRAY_TEMPL = ''' +COMMON_OBJECT_CREATE_ARRAY_TEMPL = ''' /* create an array of vkr_{vkr_type}s */ static inline VkResult vkr_{create_func_name}_create_array( @@ -143,6 +163,9 @@ vkr_{create_func_name}_create_array( }} ''' +POOL_OBJECT_CREATE_ARRAY_TEMPL = COMMON_OBJECT_CREATE_ARRAY_TEMPL +PIPELINE_OBJECT_CREATE_ARRAY_TEMPL = COMMON_OBJECT_CREATE_ARRAY_TEMPL + POOL_OBJECT_ADD_ARRAY_TEMPL = ''' /* steal vkr_{vkr_type}s from an object_array and add them to the * vkr_{pool_type} and the context @@ -171,6 +194,29 @@ void vkr_{create_func_name}_add_array( }} ''' +PIPELINE_OBJECT_ADD_ARRAY_TEMPL = ''' +/* steal vkr_{vkr_type}s from an object_array and add them to the device */ +static inline void +vkr_{create_func_name}_add_array( + struct vkr_context *ctx, + struct vkr_device *dev, + struct object_array *arr) +{{ + for (uint32_t i = 0; i < arr->count; i++) {{ + struct vkr_{vkr_type} *obj = arr->objects[i]; + + obj->base.handle.{vkr_type} = (({vk_type} *)arr->handle_storage)[i]; + + list_add(&obj->base.track_head, &dev->objects); + + vkr_device_add_object(ctx, &obj->base); + }} + + arr->objects_stolen = true; + object_array_fini(arr); +}} +''' + def apply_variant(json_obj, json_variant): tmp_obj = json_obj.copy() for key, val in json_variant.items(): @@ -247,7 +293,46 @@ def pool_object_generator(json_obj): return contents def pipeline_object_generator(json_obj): - return PIPELINE_OBJECT_DESTROY_DRIVER_HANDLE_TEMPL.format(**json_obj) + '''Generate functions for a pipeline object. + + For VkPipeline, object creation can be broken down into 3 steps + + (1) allocate and initialize the object array + (2) create the driver handles + (3) add the object array to the device and the object table + + PIPELINE_OBJECT_INIT_ARRAY_TEMPL defines a function for (1). + PIPELINE_OBJECT_CREATE_DRIVER_HANDLES_TEMPL defines a function for (2). + PIPELINE_OBJECT_CREATE_ARRAY_TEMPL defines a function for (1) and (2). + PIPELINE_OBJECT_ADD_ARRAY_TEMPL defines a function for step (3). + + Object destruction can be broken down into 2 steps + + (1) destroy the driver handle + (2) remove the object from the device and the object table + + PIPELINE_OBJECT_DESTROY_DRIVER_HANDLE_TEMPL defines a function for (1). + ''' + contents = '' + + contents += PIPELINE_OBJECT_INIT_ARRAY_TEMPL.format(**json_obj) + contents += PIPELINE_OBJECT_CREATE_DRIVER_HANDLES_TEMPL.format(**json_obj) + contents += PIPELINE_OBJECT_CREATE_ARRAY_TEMPL.format(**json_obj) + + # shared by both graphics and compute + tmp_obj = json_obj.copy() + tmp_obj['create_func_name'] = tmp_obj['vkr_type'] + contents += PIPELINE_OBJECT_ADD_ARRAY_TEMPL.format(**tmp_obj) + + contents += PIPELINE_OBJECT_DESTROY_DRIVER_HANDLE_TEMPL.format(**json_obj) + + for json_variant in json_obj['variants']: + tmp_obj = apply_variant(json_obj, json_variant) + contents += PIPELINE_OBJECT_INIT_ARRAY_TEMPL.format(**tmp_obj) + contents += PIPELINE_OBJECT_CREATE_DRIVER_HANDLES_TEMPL.format(**tmp_obj) + contents += PIPELINE_OBJECT_CREATE_ARRAY_TEMPL.format(**tmp_obj) + + return contents object_generators = { 'simple-object': simple_object_generator, diff --git a/src/venus/vkr_pipeline.c b/src/venus/vkr_pipeline.c index 27ac483..c6e3ec9 100644 --- a/src/venus/vkr_pipeline.c +++ b/src/venus/vkr_pipeline.c @@ -100,8 +100,13 @@ vkr_dispatch_vkCreateGraphicsPipelines(struct vn_dispatch_context *dispatch, struct vn_command_vkCreateGraphicsPipelines *args) { struct vkr_context *ctx = dispatch->data; + struct vkr_device *dev = (struct vkr_device *)args->device; + struct object_array arr; - CREATE_PIPELINES(vkCreateGraphicsPipelines); + if (vkr_graphics_pipeline_create_array(ctx, args, &arr) != VK_SUCCESS) + return; + + vkr_pipeline_add_array(ctx, dev, &arr); } static void @@ -109,8 +114,13 @@ vkr_dispatch_vkCreateComputePipelines(struct vn_dispatch_context *dispatch, struct vn_command_vkCreateComputePipelines *args) { struct vkr_context *ctx = dispatch->data; + struct vkr_device *dev = (struct vkr_device *)args->device; + struct object_array arr; + + if (vkr_compute_pipeline_create_array(ctx, args, &arr) != VK_SUCCESS) + return; - CREATE_PIPELINES(vkCreateComputePipelines); + vkr_pipeline_add_array(ctx, dev, &arr); } static void