mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-02-17 11:10:06 +00:00
st/oxr: Improve subImage bounds checking
This commit is contained in:
parent
981bae8d0a
commit
a69cae7516
doc/changes/state_trackers
src/xrt/state_trackers/oxr
3
doc/changes/state_trackers/mr.359.11.md
Normal file
3
doc/changes/state_trackers/mr.359.11.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
OpenXR: Validate the subImage data for both projection and quad layers layers,
|
||||||
|
refactor code out so it can be shared with the different types of layers. Need
|
||||||
|
to track some state on the `oxr_swapchain` in order to do the checking.
|
|
@ -1315,6 +1315,14 @@ struct oxr_swapchain
|
||||||
//! Compositor swapchain.
|
//! Compositor swapchain.
|
||||||
struct xrt_swapchain *swapchain;
|
struct xrt_swapchain *swapchain;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
//! Swapchain size.
|
||||||
|
uint32_t width, height;
|
||||||
|
//! For 1 is 2D texture, greater then 1 2D array texture.
|
||||||
|
uint32_t num_array_layers;
|
||||||
|
};
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
enum oxr_image_state state;
|
enum oxr_image_state state;
|
||||||
|
|
|
@ -501,6 +501,31 @@ verify_space(struct oxr_logger *log, uint32_t layer_index, XrSpace space)
|
||||||
return XR_SUCCESS;
|
return XR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static XrResult
|
||||||
|
is_rect_neg(const XrRect2Di *imageRect)
|
||||||
|
{
|
||||||
|
if (imageRect->offset.x < 0 || imageRect->offset.y < 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static XrResult
|
||||||
|
is_rect_out_of_bounds(const XrRect2Di *imageRect, struct oxr_swapchain *sc)
|
||||||
|
{
|
||||||
|
uint32_t total_width = imageRect->offset.x + imageRect->extent.width;
|
||||||
|
if (total_width > sc->width) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
uint32_t total_height = imageRect->offset.y + imageRect->extent.height;
|
||||||
|
if (total_height > sc->height) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static XrResult
|
static XrResult
|
||||||
verify_quad_layer(struct xrt_compositor *xc,
|
verify_quad_layer(struct xrt_compositor *xc,
|
||||||
struct oxr_logger *log,
|
struct oxr_logger *log,
|
||||||
|
@ -540,14 +565,15 @@ verify_quad_layer(struct xrt_compositor *xc,
|
||||||
layer_index, p->x, p->y, p->z);
|
layer_index, p->x, p->y, p->z);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
if (sc->num_array_layers <= quad->subImage.imageArrayIndex) {
|
||||||
if (quad->subImage.imageArrayIndex > 0 &&
|
return oxr_error(
|
||||||
sc->swapchain->array_size <= quad->subImage.imageArrayIndex) {
|
log, XR_ERROR_VALIDATION_FAILURE,
|
||||||
return oxr_error(log, XR_ERROR_VALIDATION_FAILURE,
|
"(frameEndInfo->layers[%u]->subImage.imageArrayIndex == "
|
||||||
"Invalid swapchain array index for layer %u.",
|
"%u) Invalid swapchain array "
|
||||||
layer_index);
|
"index for quad layer (%u).",
|
||||||
|
layer_index, quad->subImage.imageArrayIndex,
|
||||||
|
sc->num_array_layers);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!sc->released.yes) {
|
if (!sc->released.yes) {
|
||||||
return oxr_error(log, XR_ERROR_LAYER_INVALID,
|
return oxr_error(log, XR_ERROR_LAYER_INVALID,
|
||||||
|
@ -564,18 +590,25 @@ verify_quad_layer(struct xrt_compositor *xc,
|
||||||
layer_index);
|
layer_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quad->subImage.imageRect.offset.x < 0 ||
|
if (is_rect_neg(&quad->subImage.imageRect)) {
|
||||||
quad->subImage.imageRect.offset.y < 0) {
|
return oxr_error(
|
||||||
return oxr_error(log, XR_ERROR_SWAPCHAIN_RECT_INVALID,
|
log, XR_ERROR_SWAPCHAIN_RECT_INVALID,
|
||||||
"imageRect offset is negative for layer %u.",
|
"(frameEndInfo->layers[%u]->subImage.imageRect.offset == "
|
||||||
layer_index);
|
"{%i, %i}) has negative component(s)",
|
||||||
|
layer_index, quad->subImage.imageRect.offset.x,
|
||||||
|
quad->subImage.imageRect.offset.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quad->subImage.imageRect.offset.x >= 1 ||
|
if (is_rect_out_of_bounds(&quad->subImage.imageRect, sc)) {
|
||||||
quad->subImage.imageRect.offset.y >= 1) {
|
return oxr_error(
|
||||||
return oxr_error(log, XR_ERROR_SWAPCHAIN_RECT_INVALID,
|
log, XR_ERROR_SWAPCHAIN_RECT_INVALID,
|
||||||
"imageRect offset out of bounds for layer %u.",
|
"(frameEndInfo->layers[%u]->subImage.imageRect == {{%i, "
|
||||||
layer_index);
|
"%i}, {%u, %u}}) imageRect out of image bounds (%u, %u)",
|
||||||
|
layer_index, quad->subImage.imageRect.offset.x,
|
||||||
|
quad->subImage.imageRect.offset.y,
|
||||||
|
quad->subImage.imageRect.extent.width,
|
||||||
|
quad->subImage.imageRect.extent.height, sc->width,
|
||||||
|
sc->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
return XR_SUCCESS;
|
return XR_SUCCESS;
|
||||||
|
@ -603,11 +636,12 @@ verify_projection_layer(struct xrt_compositor *xc,
|
||||||
|
|
||||||
// Check for valid swapchain states.
|
// Check for valid swapchain states.
|
||||||
for (uint32_t i = 0; i < proj->viewCount; i++) {
|
for (uint32_t i = 0; i < proj->viewCount; i++) {
|
||||||
|
const XrCompositionLayerProjectionView *view = &proj->views[i];
|
||||||
|
|
||||||
//! @todo More validation?
|
//! @todo More validation?
|
||||||
if (!math_quat_validate(
|
if (!math_quat_validate(
|
||||||
(struct xrt_quat *)&proj->views[i].pose.orientation)) {
|
(struct xrt_quat *)&view->pose.orientation)) {
|
||||||
const XrQuaternionf *q =
|
const XrQuaternionf *q = &view->pose.orientation;
|
||||||
&proj->views[i].pose.orientation;
|
|
||||||
return oxr_error(
|
return oxr_error(
|
||||||
log, XR_ERROR_POSE_INVALID,
|
log, XR_ERROR_POSE_INVALID,
|
||||||
"(frameEndInfo->layers[%u]->views[%i]->pose."
|
"(frameEndInfo->layers[%u]->views[%i]->pose."
|
||||||
|
@ -616,8 +650,8 @@ verify_projection_layer(struct xrt_compositor *xc,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!math_vec3_validate(
|
if (!math_vec3_validate(
|
||||||
(struct xrt_vec3 *)&proj->views[i].pose.position)) {
|
(struct xrt_vec3 *)&view->pose.position)) {
|
||||||
const XrVector3f *p = &proj->views[i].pose.position;
|
const XrVector3f *p = &view->pose.position;
|
||||||
return oxr_error(
|
return oxr_error(
|
||||||
log, XR_ERROR_POSE_INVALID,
|
log, XR_ERROR_POSE_INVALID,
|
||||||
"(frameEndInfo->layers[%u]->views[%i]->pose."
|
"(frameEndInfo->layers[%u]->views[%i]->pose."
|
||||||
|
@ -626,7 +660,7 @@ verify_projection_layer(struct xrt_compositor *xc,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct oxr_swapchain *sc = XRT_CAST_OXR_HANDLE_TO_PTR(
|
struct oxr_swapchain *sc = XRT_CAST_OXR_HANDLE_TO_PTR(
|
||||||
struct oxr_swapchain *, proj->views[i].subImage.swapchain);
|
struct oxr_swapchain *, view->subImage.swapchain);
|
||||||
|
|
||||||
if (!sc->released.yes) {
|
if (!sc->released.yes) {
|
||||||
return oxr_error(
|
return oxr_error(
|
||||||
|
@ -643,6 +677,39 @@ verify_projection_layer(struct xrt_compositor *xc,
|
||||||
"swapchain) internal image index out of bounds",
|
"swapchain) internal image index out of bounds",
|
||||||
layer_index, i);
|
layer_index, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sc->num_array_layers <= view->subImage.imageArrayIndex) {
|
||||||
|
return oxr_error(
|
||||||
|
log, XR_ERROR_VALIDATION_FAILURE,
|
||||||
|
"(frameEndInfo->layers[%u]->views[%i]->subImage."
|
||||||
|
"imageArrayIndex == %u) Invalid swapchain array "
|
||||||
|
"index for projection layer (%u).",
|
||||||
|
layer_index, i, view->subImage.imageArrayIndex,
|
||||||
|
sc->num_array_layers);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_rect_neg(&view->subImage.imageRect)) {
|
||||||
|
return oxr_error(log, XR_ERROR_SWAPCHAIN_RECT_INVALID,
|
||||||
|
"(frameEndInfo->layers[%u]->views[%i]-"
|
||||||
|
">subImage.imageRect.offset == {%i, "
|
||||||
|
"%i}) has negative component(s)",
|
||||||
|
layer_index, i,
|
||||||
|
view->subImage.imageRect.offset.x,
|
||||||
|
view->subImage.imageRect.offset.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_rect_out_of_bounds(&view->subImage.imageRect, sc)) {
|
||||||
|
return oxr_error(
|
||||||
|
log, XR_ERROR_SWAPCHAIN_RECT_INVALID,
|
||||||
|
"(frameEndInfo->layers[%u]->views[%i]->subImage."
|
||||||
|
"imageRect == {{%i, %i}, {%u, %u}}) imageRect out "
|
||||||
|
"of image bounds (%u, %u)",
|
||||||
|
layer_index, i, view->subImage.imageRect.offset.x,
|
||||||
|
view->subImage.imageRect.offset.y,
|
||||||
|
view->subImage.imageRect.extent.width,
|
||||||
|
view->subImage.imageRect.extent.height, sc->width,
|
||||||
|
sc->height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return XR_SUCCESS;
|
return XR_SUCCESS;
|
||||||
|
|
|
@ -200,6 +200,9 @@ oxr_create_swapchain(struct oxr_logger *log,
|
||||||
oxr_swapchain_destroy, &sess->handle);
|
oxr_swapchain_destroy, &sess->handle);
|
||||||
sc->sess = sess;
|
sc->sess = sess;
|
||||||
sc->swapchain = xsc;
|
sc->swapchain = xsc;
|
||||||
|
sc->width = createInfo->width;
|
||||||
|
sc->height = createInfo->height;
|
||||||
|
sc->num_array_layers = createInfo->arraySize;
|
||||||
sc->acquire_image = oxr_swapchain_acquire_image;
|
sc->acquire_image = oxr_swapchain_acquire_image;
|
||||||
sc->wait_image = oxr_swapchain_wait_image;
|
sc->wait_image = oxr_swapchain_wait_image;
|
||||||
sc->release_image = oxr_swapchain_release_image;
|
sc->release_image = oxr_swapchain_release_image;
|
||||||
|
|
Loading…
Reference in a new issue