| // Copyright 2017-2020 The Khronos Group. This work is licensed under a |
| // Creative Commons Attribution 4.0 International License; see |
| // http://creativecommons.org/licenses/by/4.0/ |
| |
| [appendix] |
| [[check-copy-overlap]] |
| = Checking for Memory Copy Overlap |
| |
| The following code describes how to determine if there is overlap between |
| the source and destination rectangles specified to {clEnqueueCopyBufferRect} |
| provided the source and destination buffers refer to the same buffer object. |
| |
| [source,c] |
| ---- |
| unsigned int |
| check_copy_overlap(const size_t src_origin[], |
| const size_t dst_origin[], |
| const size_t region[], |
| const size_t row_pitch, |
| const size_t slice_pitch ) |
| { |
| const size_t slice_size = (region[1] - 1) * row_pitch + region[0]; |
| const size_t block_size = (region[2] - 1) * slice_pitch + slice_size; |
| const size_t src_start = src_origin[2] * slice_pitch |
| + src_origin[1] * row_pitch |
| + src_origin[0]; |
| const size_t src_end = src_start + block_size; |
| const size_t dst_start = dst_origin[2] * slice_pitch |
| + dst_origin[1] * row_pitch |
| + dst_origin[0]; |
| const size_t dst_end = dst_start + block_size; |
| |
| /* No overlap if dst ends before src starts or if src ends |
| * before dst starts. |
| */ |
| if( (dst_end <= src_start) || (src_end <= dst_start) ){ |
| return 0; |
| } |
| |
| /* No overlap if region[0] for dst or src fits in the gap |
| * between region[0] and row_pitch. |
| */ |
| { |
| const size_t src_dx = src_origin[0] % row_pitch; |
| const size_t dst_dx = dst_origin[0] % row_pitch; |
| |
| if( ((dst_dx >= src_dx + region[0]) && |
| (dst_dx + region[0] <= src_dx + row_pitch)) || |
| ((src_dx >= dst_dx + region[0]) && |
| (src_dx + region[0] <= dst_dx + row_pitch)) ) |
| { |
| return 0; |
| } |
| } |
| |
| /* No overlap if region[1] for dst or src fits in the gap |
| * between region[1] and slice_pitch. |
| */ |
| { |
| const size_t src_dy = |
| (src_origin[1] * row_pitch + src_origin[0]) % slice_pitch; |
| const size_t dst_dy = |
| (dst_origin[1] * row_pitch + dst_origin[0]) % slice_pitch; |
| |
| if( ((dst_dy >= src_dy + slice_size) && |
| (dst_dy + slice_size <= src_dy + slice_pitch)) || |
| ((src_dy >= dst_dy + slice_size) && |
| (src_dy + slice_size <= dst_dy + slice_pitch)) ) { |
| return 0; |
| } |
| } |
| |
| /* Otherwise src and dst overlap. */ |
| return 1; |
| } |
| ---- |