The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

st/oxr: Add equirect2 verify and submit functions.

authored by

Lubosz Sarnecki and committed by
Jakob Bornecrantz
1227c775 3195ba83

+178
+178
src/xrt/state_trackers/oxr/oxr_session.c
··· 1266 1266 #endif 1267 1267 } 1268 1268 1269 + static XrResult 1270 + verify_equirect2_layer(struct xrt_compositor *xc, 1271 + struct oxr_logger *log, 1272 + uint32_t layer_index, 1273 + const XrCompositionLayerEquirect2KHR *equirect, 1274 + struct xrt_device *head, 1275 + uint64_t timestamp) 1276 + { 1277 + #ifndef XRT_FEATURE_OPENXR_LAYER_EQUIRECT 1278 + return oxr_error(log, XR_ERROR_LAYER_INVALID, 1279 + "(frameEndInfo->layers[%u]->type) layer type " 1280 + "XrCompositionLayerEquirect2KHR not supported", 1281 + layer_index); 1282 + #else 1283 + struct oxr_swapchain *sc = XRT_CAST_OXR_HANDLE_TO_PTR( 1284 + struct oxr_swapchain *, equirect->subImage.swapchain); 1285 + 1286 + if (sc == NULL) { 1287 + return oxr_error(log, XR_ERROR_LAYER_INVALID, 1288 + "(frameEndInfo->layers[%u]->subImage." 1289 + "swapchain) swapchain is NULL!", 1290 + layer_index); 1291 + } 1292 + 1293 + XrResult ret = verify_space(log, layer_index, equirect->space); 1294 + if (ret != XR_SUCCESS) { 1295 + return ret; 1296 + } 1297 + 1298 + if (!math_quat_validate( 1299 + (struct xrt_quat *)&equirect->pose.orientation)) { 1300 + const XrQuaternionf *q = &equirect->pose.orientation; 1301 + return oxr_error(log, XR_ERROR_POSE_INVALID, 1302 + "(frameEndInfo->layers[%u]->pose.orientation " 1303 + "== {%f %f %f %f}) is not a valid quat", 1304 + layer_index, q->x, q->y, q->z, q->w); 1305 + } 1306 + 1307 + if (!math_vec3_validate((struct xrt_vec3 *)&equirect->pose.position)) { 1308 + const XrVector3f *p = &equirect->pose.position; 1309 + return oxr_error(log, XR_ERROR_POSE_INVALID, 1310 + "(frameEndInfo->layers[%u]->pose.position == " 1311 + "{%f %f %f}) is not valid", 1312 + layer_index, p->x, p->y, p->z); 1313 + } 1314 + 1315 + if (sc->num_array_layers <= equirect->subImage.imageArrayIndex) { 1316 + return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, 1317 + "(frameEndInfo->layers[%u]->subImage." 1318 + "imageArrayIndex == %u) Invalid swapchain " 1319 + "array index for equirect layer (%u).", 1320 + layer_index, 1321 + equirect->subImage.imageArrayIndex, 1322 + sc->num_array_layers); 1323 + } 1324 + 1325 + if (!sc->released.yes) { 1326 + return oxr_error(log, XR_ERROR_LAYER_INVALID, 1327 + "(frameEndInfo->layers[%u]->subImage." 1328 + "swapchain) swapchain has not been released!", 1329 + layer_index); 1330 + } 1331 + 1332 + if (sc->released.index >= (int)sc->swapchain->num_images) { 1333 + return oxr_error( 1334 + log, XR_ERROR_RUNTIME_FAILURE, 1335 + "(frameEndInfo->layers[%u]->subImage.swapchain) internal " 1336 + "image index out of bounds", 1337 + layer_index); 1338 + } 1339 + 1340 + if (is_rect_neg(&equirect->subImage.imageRect)) { 1341 + return oxr_error( 1342 + log, XR_ERROR_SWAPCHAIN_RECT_INVALID, 1343 + "(frameEndInfo->layers[%u]->subImage.imageRect.offset == " 1344 + "{%i, %i}) has negative component(s)", 1345 + layer_index, equirect->subImage.imageRect.offset.x, 1346 + equirect->subImage.imageRect.offset.y); 1347 + } 1348 + 1349 + if (is_rect_out_of_bounds(&equirect->subImage.imageRect, sc)) { 1350 + return oxr_error( 1351 + log, XR_ERROR_SWAPCHAIN_RECT_INVALID, 1352 + "(frameEndInfo->layers[%u]->subImage.imageRect == {{%i, " 1353 + "%i}, {%u, %u}}) imageRect out of image bounds (%u, %u)", 1354 + layer_index, equirect->subImage.imageRect.offset.x, 1355 + equirect->subImage.imageRect.offset.y, 1356 + equirect->subImage.imageRect.extent.width, 1357 + equirect->subImage.imageRect.extent.height, sc->width, 1358 + sc->height); 1359 + } 1360 + 1361 + if (equirect->centralHorizontalAngle < .0f) { 1362 + return oxr_error( 1363 + log, XR_ERROR_VALIDATION_FAILURE, 1364 + "(frameEndInfo->layers[%u]->centralHorizontalAngle == %f) " 1365 + "centralHorizontalAngle out of bounds", 1366 + layer_index, equirect->centralHorizontalAngle); 1367 + } 1368 + 1369 + /* 1370 + * Accept all angle ranges here, since we are dealing with π 1371 + * and we don't want floating point errors to prevent the client 1372 + * to display the full sphere. 1373 + */ 1374 + 1375 + return XR_SUCCESS; 1376 + #endif 1377 + } 1378 + 1269 1379 static enum xrt_layer_composition_flags 1270 1380 convert_layer_flags(XrSwapchainUsageFlags xr_flags) 1271 1381 { ··· 1655 1765 } 1656 1766 } 1657 1767 1768 + static XrResult 1769 + submit_equirect2_layer(struct oxr_session *sess, 1770 + struct xrt_compositor *xc, 1771 + struct oxr_logger *log, 1772 + const XrCompositionLayerEquirect2KHR *equirect, 1773 + struct xrt_device *head, 1774 + struct xrt_pose *inv_offset, 1775 + uint64_t timestamp) 1776 + { 1777 + struct oxr_swapchain *sc = XRT_CAST_OXR_HANDLE_TO_PTR( 1778 + struct oxr_swapchain *, equirect->subImage.swapchain); 1779 + struct oxr_space *spc = 1780 + XRT_CAST_OXR_HANDLE_TO_PTR(struct oxr_space *, equirect->space); 1781 + 1782 + enum xrt_layer_composition_flags flags = 1783 + convert_layer_flags(equirect->layerFlags); 1784 + 1785 + struct xrt_pose *pose_ptr = (struct xrt_pose *)&equirect->pose; 1786 + 1787 + struct xrt_pose pose; 1788 + if (!handle_space(log, sess, spc, pose_ptr, inv_offset, timestamp, 1789 + &pose)) { 1790 + return XR_SUCCESS; 1791 + } 1792 + 1793 + if (spc->is_reference && spc->type == XR_REFERENCE_SPACE_TYPE_VIEW) { 1794 + flags |= XRT_LAYER_COMPOSITION_VIEW_SPACE_BIT; 1795 + } 1796 + 1797 + struct xrt_layer_data data; 1798 + U_ZERO(&data); 1799 + data.type = XRT_LAYER_EQUIRECT; 1800 + data.name = XRT_INPUT_GENERIC_HEAD_POSE; 1801 + data.timestamp = timestamp; 1802 + data.flags = flags; 1803 + 1804 + struct xrt_rect *rect = 1805 + (struct xrt_rect *)&equirect->subImage.imageRect; 1806 + 1807 + data.equirect.visibility = 1808 + convert_eye_visibility(equirect->eyeVisibility); 1809 + data.equirect.sub.image_index = sc->released.index; 1810 + data.equirect.sub.array_index = equirect->subImage.imageArrayIndex; 1811 + data.equirect.sub.rect = *rect; 1812 + data.equirect.pose = pose; 1813 + 1814 + data.equirect.radius = equirect->radius; 1815 + data.equirect.central_horizontal_angle = 1816 + equirect->centralHorizontalAngle; 1817 + data.equirect.upper_vertical_angle = equirect->upperVerticalAngle; 1818 + data.equirect.lower_vertical_angle = equirect->lowerVerticalAngle; 1819 + 1820 + CALL_CHK(xrt_comp_layer_equirect(xc, head, sc->swapchain, &data)); 1821 + 1822 + return XR_SUCCESS; 1823 + } 1824 + 1658 1825 XrResult 1659 1826 oxr_session_frame_end(struct oxr_logger *log, 1660 1827 struct oxr_session *sess, ··· 1782 1949 xc, log, i, (XrCompositionLayerEquirectKHR *)layer, 1783 1950 xdev, frameEndInfo->displayTime); 1784 1951 break; 1952 + case XR_TYPE_COMPOSITION_LAYER_EQUIRECT2_KHR: 1953 + res = verify_equirect2_layer( 1954 + xc, log, i, (XrCompositionLayerEquirect2KHR *)layer, 1955 + xdev, frameEndInfo->displayTime); 1956 + break; 1785 1957 default: 1786 1958 return oxr_error(log, XR_ERROR_LAYER_INVALID, 1787 1959 "(frameEndInfo->layers[%u]->type) " ··· 1838 2010 submit_equirect_layer( 1839 2011 sess, xc, log, 1840 2012 (XrCompositionLayerEquirectKHR *)layer, xdev, 2013 + &inv_offset, frameEndInfo->displayTime); 2014 + break; 2015 + case XR_TYPE_COMPOSITION_LAYER_EQUIRECT2_KHR: 2016 + submit_equirect2_layer( 2017 + sess, xc, log, 2018 + (XrCompositionLayerEquirect2KHR *)layer, xdev, 1841 2019 &inv_offset, frameEndInfo->displayTime); 1842 2020 break; 1843 2021 default: assert(false && "invalid layer type");