From dffb94a3b249b0981c7e0c4471e643a9950bb624 Mon Sep 17 00:00:00 2001 From: Rylie Pavlik Date: Fri, 6 Dec 2024 10:27:33 -0600 Subject: [PATCH 1/6] CTS layer: general cleanup of handle creation --- src/scripts/template_gen_dispatch.cpp | 35 +++++++++++++++------------ 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/scripts/template_gen_dispatch.cpp b/src/scripts/template_gen_dispatch.cpp index 57163776..51a11177 100644 --- a/src/scripts/template_gen_dispatch.cpp +++ b/src/scripts/template_gen_dispatch.cpp @@ -48,9 +48,9 @@ /*{ cur_cmd.cdecl | collapse_whitespace | replace(" xr", " ConformanceLayer_xr") | replace(";", "") }*/ { -//# set first_param_object_type = gen.genXrObjectType(handle_type) +//# set first_handle_object_type = gen.genXrObjectType(handle_type) try { - HandleState* const handleState = GetHandleState({HandleToInt(/*{first_handle_name}*/), /*{first_param_object_type}*/}); + HandleState* const handleState = GetHandleState({HandleToInt(/*{ first_handle_name }*/), /*{ first_handle_object_type }*/}); return handleState->conformanceHooks->/*{cur_cmd.name}*/(/*{ cur_cmd.params | map(attribute="name") | join(", ") }*/); } @@ -97,19 +97,22 @@ //# set is_destroy = (("xrDestroy" in cur_cmd.name) and is_last_arg_handle) //# if is_create or is_destroy if (XR_SUCCEEDED(result)) { -//# set last_param_name = cur_cmd.params[-1].name -//# set last_param_type = cur_cmd.params[-1].type -//# set last_param_object_type = gen.genXrObjectType(last_param_type) +//# set out_handle_param_name = cur_cmd.params[-1].name +//# set out_handle_type = cur_cmd.params[-1].type +//# set out_handle_object_type = gen.genXrObjectType(out_handle_type) //# if is_create - HandleState* const parentHandleState = GetHandleState(HandleStateKey{HandleToInt(/*{first_handle_name}*/), /*{first_param_object_type}*/}); - RegisterHandleState(parentHandleState->CloneForChild(HandleToInt(* /*{last_param_name}*/), /*{last_param_object_type}*/)); + HandleState* const parentHandleState = GetHandleState(HandleStateKey{HandleToInt(/*{ first_handle_name }*/), /*{ first_handle_object_type }*/}); + RegisterHandleState(parentHandleState->CloneForChild(HandleToInt(* /*{ out_handle_param_name }*/), /*{ out_handle_object_type }*/)); //# endif //# if is_destroy - UnregisterHandleState({HandleToInt(/*{last_param_name}*/), /*{last_param_object_type}*/}); + UnregisterHandleState({HandleToInt(/*{ first_handle_name }*/), /*{ first_handle_object_type }*/}); //# endif } //# endif +//## ### Special Case Handle Creation Follows ### +//## Dealing with other ways that handles come into our world + //## If this is a xrQuerySpacesFB, we have to create an entry in //## the appropriate unordered_map pointing to the correct dispatch table for //## the newly created objects. @@ -117,9 +120,9 @@ //# set is_query_spaces = ("xrQuerySpacesFB" == cur_cmd.name) //# if is_create_spatial_anchor or is_query_spaces if (XR_SUCCEEDED(result)) { -//# set last_param_name = cur_cmd.params[-1].name - HandleState* const parentHandleState = GetHandleState(HandleStateKey{HandleToInt(/*{first_handle_name}*/), XR_OBJECT_TYPE_SESSION}); - RegisterHandleState(parentHandleState->CloneForChild(* /*{last_param_name}*/, static_cast(XR_TYPE_EVENT_DATA_SPATIAL_ANCHOR_CREATE_COMPLETE_FB))); +//# set out_handle_name = cur_cmd.params[-1].name + HandleState* const parentHandleState = GetHandleState(HandleStateKey{HandleToInt(/*{ first_handle_name }*/), XR_OBJECT_TYPE_SESSION}); + RegisterHandleState(parentHandleState->CloneForChild(* /*{ out_handle_name }*/, static_cast(XR_TYPE_EVENT_DATA_SPATIAL_ANCHOR_CREATE_COMPLETE_FB))); } //# endif @@ -144,11 +147,11 @@ //# set is_space_query_results = ("xrRetrieveSpaceQueryResultsFB" == cur_cmd.name) //# if is_space_query_results if (XR_SUCCEEDED(result)) { -//# set last_param_name = cur_cmd.params[-1].name - if (/*{last_param_name}*/->results) { - for (uint32_t i = 0; i < /*{last_param_name}*/->resultCountOutput; ++i) { - HandleState* const parentHandleState = GetHandleState(HandleStateKey{HandleToInt(/*{first_handle_name}*/), XR_OBJECT_TYPE_SESSION}); - RegisterHandleState(parentHandleState->CloneForChild(HandleToInt(/*{last_param_name}*/->results[i].space), XR_OBJECT_TYPE_SPACE)); +//# set out_param_name = cur_cmd.params[-1].name + if (/*{ out_param_name }*/->results) { + for (uint32_t i = 0; i < /*{ out_param_name }*/->resultCountOutput; ++i) { + HandleState* const parentHandleState = GetHandleState(HandleStateKey{HandleToInt(/*{ first_handle_name }*/), XR_OBJECT_TYPE_SESSION}); + RegisterHandleState(parentHandleState->CloneForChild(HandleToInt(/*{ out_param_name }*/->results[i].space), XR_OBJECT_TYPE_SPACE)); } } } From ceee1cae1a560aedfc8d33c4ab503422dd7bbe72 Mon Sep 17 00:00:00 2001 From: Rylie Pavlik Date: Fri, 6 Dec 2024 11:08:13 -0600 Subject: [PATCH 2/6] CTS layer: Remove unneeded explicit type name mention --- src/scripts/template_gen_dispatch.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/scripts/template_gen_dispatch.cpp b/src/scripts/template_gen_dispatch.cpp index 51a11177..c2f79888 100644 --- a/src/scripts/template_gen_dispatch.cpp +++ b/src/scripts/template_gen_dispatch.cpp @@ -101,7 +101,7 @@ //# set out_handle_type = cur_cmd.params[-1].type //# set out_handle_object_type = gen.genXrObjectType(out_handle_type) //# if is_create - HandleState* const parentHandleState = GetHandleState(HandleStateKey{HandleToInt(/*{ first_handle_name }*/), /*{ first_handle_object_type }*/}); + HandleState* const parentHandleState = GetHandleState({HandleToInt(/*{ first_handle_name }*/), /*{ first_handle_object_type }*/}); RegisterHandleState(parentHandleState->CloneForChild(HandleToInt(* /*{ out_handle_param_name }*/), /*{ out_handle_object_type }*/)); //# endif //# if is_destroy @@ -121,7 +121,7 @@ //# if is_create_spatial_anchor or is_query_spaces if (XR_SUCCEEDED(result)) { //# set out_handle_name = cur_cmd.params[-1].name - HandleState* const parentHandleState = GetHandleState(HandleStateKey{HandleToInt(/*{ first_handle_name }*/), XR_OBJECT_TYPE_SESSION}); + HandleState* const parentHandleState = GetHandleState({HandleToInt(/*{ first_handle_name }*/), XR_OBJECT_TYPE_SESSION}); RegisterHandleState(parentHandleState->CloneForChild(* /*{ out_handle_name }*/, static_cast(XR_TYPE_EVENT_DATA_SPATIAL_ANCHOR_CREATE_COMPLETE_FB))); } //# endif @@ -134,7 +134,7 @@ if (XR_SUCCEEDED(result)) { if (eventData->type == XR_TYPE_EVENT_DATA_SPATIAL_ANCHOR_CREATE_COMPLETE_FB) { XrEventDataSpatialAnchorCreateCompleteFB* completeEvent = reinterpret_cast(eventData); - HandleState* const requestStateObject = GetHandleState(HandleStateKey{(IntHandle)completeEvent->requestId, static_cast(XR_TYPE_EVENT_DATA_SPATIAL_ANCHOR_CREATE_COMPLETE_FB)}); + HandleState* const requestStateObject = GetHandleState({(IntHandle)completeEvent->requestId, static_cast(XR_TYPE_EVENT_DATA_SPATIAL_ANCHOR_CREATE_COMPLETE_FB)}); HandleState* const parentHandleState = requestStateObject->parent; // session RegisterHandleState(parentHandleState->CloneForChild(HandleToInt(completeEvent->space), XR_OBJECT_TYPE_SPACE)); } @@ -150,7 +150,7 @@ //# set out_param_name = cur_cmd.params[-1].name if (/*{ out_param_name }*/->results) { for (uint32_t i = 0; i < /*{ out_param_name }*/->resultCountOutput; ++i) { - HandleState* const parentHandleState = GetHandleState(HandleStateKey{HandleToInt(/*{ first_handle_name }*/), XR_OBJECT_TYPE_SESSION}); + HandleState* const parentHandleState = GetHandleState({HandleToInt(/*{ first_handle_name }*/), XR_OBJECT_TYPE_SESSION}); RegisterHandleState(parentHandleState->CloneForChild(HandleToInt(/*{ out_param_name }*/->results[i].space), XR_OBJECT_TYPE_SPACE)); } } From 612647ab52ce6202456406db20469fa79096281f Mon Sep 17 00:00:00 2001 From: Rylie Pavlik Date: Fri, 6 Dec 2024 10:34:58 -0600 Subject: [PATCH 3/6] CTS layer: Code docs --- src/conformance/conformance_layer/HandleState.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/conformance/conformance_layer/HandleState.h b/src/conformance/conformance_layer/HandleState.h index c6dc8551..7c6c817d 100644 --- a/src/conformance/conformance_layer/HandleState.h +++ b/src/conformance/conformance_layer/HandleState.h @@ -123,9 +123,14 @@ struct HandleNotFoundException : public HandleException } }; +/// Global handle state map key: The value of a handle as an int, and its XrObjectType enumerant. using HandleStateKey = std::pair; +/// Destroy a handle state object owned by the global handle state map. void UnregisterHandleState(HandleStateKey key); + +/// Transfer ownership of a handle state object to the global handle state map. +/// Usually called directly with the return value of @ref HandleState::CloneForChild void RegisterHandleState(std::unique_ptr handleState); /// Retrieve common handle state based on a handle and object type enum. From 2480306ae67e34d84076e564dedcf5940cec98fe Mon Sep 17 00:00:00 2001 From: Rylie Pavlik Date: Fri, 6 Dec 2024 10:35:14 -0600 Subject: [PATCH 4/6] CTS layer: Add helper function for handle creation --- src/conformance/conformance_layer/HandleState.cpp | 7 +++++++ src/conformance/conformance_layer/HandleState.h | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/src/conformance/conformance_layer/HandleState.cpp b/src/conformance/conformance_layer/HandleState.cpp index bd48a214..d2f7eb2f 100644 --- a/src/conformance/conformance_layer/HandleState.cpp +++ b/src/conformance/conformance_layer/HandleState.cpp @@ -55,6 +55,13 @@ void RegisterHandleState(std::unique_ptr handleState) } } +void CreateAndRegisterHandleState(HandleStateKey parentHandleKey, HandleStateKey handleKey) +{ + + HandleState* const parentHandleState = GetHandleState(parentHandleKey); + RegisterHandleState(parentHandleState->CloneForChild(handleKey.first, handleKey.second)); +} + void UnregisterHandleStateInternal(std::unique_lock& lockProof, HandleStateKey key) { auto it = g_handleStates.find(key); diff --git a/src/conformance/conformance_layer/HandleState.h b/src/conformance/conformance_layer/HandleState.h index 7c6c817d..36a46445 100644 --- a/src/conformance/conformance_layer/HandleState.h +++ b/src/conformance/conformance_layer/HandleState.h @@ -133,6 +133,10 @@ void UnregisterHandleState(HandleStateKey key); /// Usually called directly with the return value of @ref HandleState::CloneForChild void RegisterHandleState(std::unique_ptr handleState); +/// Combines @ref GetHandleState for the parent handle, @ref HandleState::CloneForChild, and @ref RegisterHandleState +/// since they are frequently used together in this single configuration. +void CreateAndRegisterHandleState(HandleStateKey parentHandleKey, HandleStateKey handleKey); + /// Retrieve common handle state based on a handle and object type enum. /// Throws if not found. HandleState* GetHandleState(HandleStateKey key); From eda0a96d6c83ee7946b6137abd7f44b95ca6caae Mon Sep 17 00:00:00 2001 From: Rylie Pavlik Date: Fri, 6 Dec 2024 10:39:03 -0600 Subject: [PATCH 5/6] CTS layer: Port generated code dealing with new handles to use the new function --- src/scripts/template_gen_dispatch.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/scripts/template_gen_dispatch.cpp b/src/scripts/template_gen_dispatch.cpp index c2f79888..aff6d4d7 100644 --- a/src/scripts/template_gen_dispatch.cpp +++ b/src/scripts/template_gen_dispatch.cpp @@ -101,8 +101,9 @@ //# set out_handle_type = cur_cmd.params[-1].type //# set out_handle_object_type = gen.genXrObjectType(out_handle_type) //# if is_create - HandleState* const parentHandleState = GetHandleState({HandleToInt(/*{ first_handle_name }*/), /*{ first_handle_object_type }*/}); - RegisterHandleState(parentHandleState->CloneForChild(HandleToInt(* /*{ out_handle_param_name }*/), /*{ out_handle_object_type }*/)); + CreateAndRegisterHandleState( + {HandleToInt(/*{ first_handle_name }*/), /*{ first_handle_object_type }*/}, + {HandleToInt(* /*{ out_handle_param_name }*/), /*{ out_handle_object_type }*/}); //# endif //# if is_destroy UnregisterHandleState({HandleToInt(/*{ first_handle_name }*/), /*{ first_handle_object_type }*/}); @@ -121,8 +122,9 @@ //# if is_create_spatial_anchor or is_query_spaces if (XR_SUCCEEDED(result)) { //# set out_handle_name = cur_cmd.params[-1].name - HandleState* const parentHandleState = GetHandleState({HandleToInt(/*{ first_handle_name }*/), XR_OBJECT_TYPE_SESSION}); - RegisterHandleState(parentHandleState->CloneForChild(* /*{ out_handle_name }*/, static_cast(XR_TYPE_EVENT_DATA_SPATIAL_ANCHOR_CREATE_COMPLETE_FB))); + CreateAndRegisterHandleState( + {HandleToInt(/*{ first_handle_name }*/), XR_OBJECT_TYPE_SESSION}, + {* /*{ out_handle_name }*/, static_cast(XR_TYPE_EVENT_DATA_SPATIAL_ANCHOR_CREATE_COMPLETE_FB)}); } //# endif @@ -150,8 +152,9 @@ //# set out_param_name = cur_cmd.params[-1].name if (/*{ out_param_name }*/->results) { for (uint32_t i = 0; i < /*{ out_param_name }*/->resultCountOutput; ++i) { - HandleState* const parentHandleState = GetHandleState({HandleToInt(/*{ first_handle_name }*/), XR_OBJECT_TYPE_SESSION}); - RegisterHandleState(parentHandleState->CloneForChild(HandleToInt(/*{ out_param_name }*/->results[i].space), XR_OBJECT_TYPE_SPACE)); + CreateAndRegisterHandleState( + {HandleToInt(/*{ first_handle_name }*/), XR_OBJECT_TYPE_SESSION}, + {HandleToInt(/*{ out_param_name }*/->results[i].space), XR_OBJECT_TYPE_SPACE}); } } } From 7eddcb7583f0daf671c9a70af48ab9cc4ec21a92 Mon Sep 17 00:00:00 2001 From: Rylie Pavlik Date: Fri, 6 Dec 2024 11:00:26 -0600 Subject: [PATCH 6/6] CTS layer: More cleanup and docs --- src/scripts/template_gen_dispatch.cpp | 45 ++++++++++++++++----------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/src/scripts/template_gen_dispatch.cpp b/src/scripts/template_gen_dispatch.cpp index aff6d4d7..274de5d5 100644 --- a/src/scripts/template_gen_dispatch.cpp +++ b/src/scripts/template_gen_dispatch.cpp @@ -75,14 +75,14 @@ //## Leading false allows each generated entry to start with || bool recognizedReturnCode = (false //## Core return codes - /*% for val in cur_cmd.return_values %*/ || /*{ checkResult(val) }*/ /*% endfor %*/ + /*%- for val in cur_cmd.return_values %*/ || /*{ checkResult(val) }*/ /*% endfor -%*/ //## Extension return codes, if any -//# for ext_code in ext_return_codes +//#- for ext_code in ext_return_codes //# if ext_code.command == cur_cmd.name || /*{ checkExtCode(ext_code) }*/ -//# endif -//# endfor +//#- endif +//#- endfor ); if (!recognizedReturnCode) { this->ConformanceFailure(XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, /*{ cur_cmd.name | quote_string }*/, "Illegal result code returned: %d", result); @@ -90,24 +90,28 @@ //## If this is a create command, we have to create an entry in the appropriate //## unordered_map pointing to the correct dispatch table for the newly created -//## object. Likewise, if it's a delete command, we have to remove the entry -//## for the dispatch table from the unordered_map -//# set is_last_arg_handle = (cur_cmd.params[-1].is_handle) +//## object. +//#- set is_last_arg_handle = (cur_cmd.params[-1].is_handle) //# set is_create = (("xrCreate" in cur_cmd.name) and is_last_arg_handle) -//# set is_destroy = (("xrDestroy" in cur_cmd.name) and is_last_arg_handle) -//# if is_create or is_destroy +//# if is_create if (XR_SUCCEEDED(result)) { //# set out_handle_param_name = cur_cmd.params[-1].name //# set out_handle_type = cur_cmd.params[-1].type //# set out_handle_object_type = gen.genXrObjectType(out_handle_type) -//# if is_create + // Normal "xrCreate" function: create and register state for child handle CreateAndRegisterHandleState( {HandleToInt(/*{ first_handle_name }*/), /*{ first_handle_object_type }*/}, {HandleToInt(* /*{ out_handle_param_name }*/), /*{ out_handle_object_type }*/}); -//# endif -//# if is_destroy + } +//# endif + +//## Likewise, if it's a delete command, we have to remove the entry +//## for the dispatch table from the unordered_map +//#- set is_destroy = (("xrDestroy" in cur_cmd.name) and is_last_arg_handle) +//# if is_destroy + if (XR_SUCCEEDED(result)) { + // Normal "xrDestroy" function: unregister/destroy state for handle UnregisterHandleState({HandleToInt(/*{ first_handle_name }*/), /*{ first_handle_object_type }*/}); -//# endif } //# endif @@ -117,11 +121,13 @@ //## If this is a xrQuerySpacesFB, we have to create an entry in //## the appropriate unordered_map pointing to the correct dispatch table for //## the newly created objects. -//# set is_create_spatial_anchor = ("xrCreateSpatialAnchorFB" == cur_cmd.name) +//#- set is_create_spatial_anchor = ("xrCreateSpatialAnchorFB" == cur_cmd.name) //# set is_query_spaces = ("xrQuerySpacesFB" == cur_cmd.name) //# if is_create_spatial_anchor or is_query_spaces if (XR_SUCCEEDED(result)) { //# set out_handle_name = cur_cmd.params[-1].name + // Create "handle state" for the XrAsyncRequestIdFB value, with "object type" of the completion event expected. + // The session is considered the parent handle. CreateAndRegisterHandleState( {HandleToInt(/*{ first_handle_name }*/), XR_OBJECT_TYPE_SESSION}, {* /*{ out_handle_name }*/, static_cast(XR_TYPE_EVENT_DATA_SPATIAL_ANCHOR_CREATE_COMPLETE_FB)}); @@ -131,13 +137,15 @@ //## If this is a xrPollEvent and the event type returns an object, we have to //## create an entry in the appropriate unordered_map pointing to the correct //## dispatch table for the newly created object. -//# set is_pollevent = ("xrPollEvent" == cur_cmd.name) +//#- set is_pollevent = ("xrPollEvent" == cur_cmd.name) //# if is_pollevent if (XR_SUCCEEDED(result)) { if (eventData->type == XR_TYPE_EVENT_DATA_SPATIAL_ANCHOR_CREATE_COMPLETE_FB) { + // Deal with new handle being returned in an async completion event. XrEventDataSpatialAnchorCreateCompleteFB* completeEvent = reinterpret_cast(eventData); + // Lookup "handle state" for the XrAsyncRequestIdFB value, with "object type" of the event struct type. HandleState* const requestStateObject = GetHandleState({(IntHandle)completeEvent->requestId, static_cast(XR_TYPE_EVENT_DATA_SPATIAL_ANCHOR_CREATE_COMPLETE_FB)}); - HandleState* const parentHandleState = requestStateObject->parent; // session + HandleState* const parentHandleState = requestStateObject->parent; // session: parent of request ID RegisterHandleState(parentHandleState->CloneForChild(HandleToInt(completeEvent->space), XR_OBJECT_TYPE_SPACE)); } } @@ -146,10 +154,11 @@ //## If this is a xrRetrieveSpaceQueryResultsFB, we have to create an entry in //## the appropriate unordered_map pointing to the correct dispatch table for //## the newly created objects. -//# set is_space_query_results = ("xrRetrieveSpaceQueryResultsFB" == cur_cmd.name) +//#- set is_space_query_results = ("xrRetrieveSpaceQueryResultsFB" == cur_cmd.name) //# if is_space_query_results if (XR_SUCCEEDED(result)) { //# set out_param_name = cur_cmd.params[-1].name + // Deal with created space handles if (/*{ out_param_name }*/->results) { for (uint32_t i = 0; i < /*{ out_param_name }*/->resultCountOutput; ++i) { CreateAndRegisterHandleState( @@ -160,8 +169,6 @@ } //# endif - - return result; }