+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)",
+ where);
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Perform PBO validation for read operations with compressed textures.
+ * If any GL errors are detected, false is returned, otherwise returns true.
+ */
+bool
+_mesa_validate_pbo_source_compressed(struct gl_context *ctx, GLuint dimensions,
+ const struct gl_pixelstore_attrib *unpack,
+ GLsizei imageSize, const GLvoid *pixels,
+ const char *where)
+{
+ if (!_mesa_is_bufferobj(unpack->BufferObj)) {
+ /* not using a PBO */
+ return true;
+ }
+
+ if ((const GLubyte *) pixels + imageSize >
+ ((const GLubyte *) 0) + unpack->BufferObj->Size) {
+ /* out of bounds read! */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid PBO access)",
+ where);
+ return false;
+ }
+
+ if (_mesa_check_disallowed_mapping(unpack->BufferObj)) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)",
+ where);
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Perform PBO-read mapping.
+ * If any GL errors are detected, they'll be recorded and NULL returned.
+ * \sa _mesa_validate_pbo_source
+ * \sa _mesa_map_pbo_source
+ * A call to this function should have a matching call to
+ * _mesa_unmap_pbo_source().
+ */
+const GLvoid *
+_mesa_map_validate_pbo_source(struct gl_context *ctx,
+ GLuint dimensions,
+ const struct gl_pixelstore_attrib *unpack,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type,
+ GLsizei clientMemSize,
+ const GLvoid *ptr, const char *where)
+{
+ if (!_mesa_validate_pbo_source(ctx, dimensions, unpack,
+ width, height, depth, format, type,
+ clientMemSize, ptr, where)) {
+ return NULL;