lwjgl/src/java/org/lwjgl/opencl/CLChecks.java

270 lines
8.7 KiB
Java

/*
* Copyright (c) 2002-2010 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opencl;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.PointerBuffer;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import static org.lwjgl.opencl.CL10.*;
import static org.lwjgl.opencl.CL11.*;
/**
* Utility class that provides runtime checks for OpenCL method calls.
* TODO: Revisit this when Java 7.0 is released, there will be new Buffer API with 64bit indices/sizes.
*
* @author Spasi
*/
final class CLChecks {
private CLChecks() {
}
/**
* Calculates the number of bytes in the specified cl_mem buffer rectangle region.
*
* @param offset the host offset
* @param region the rectangle region
* @param row_pitch the host row pitch
* @param slice_pitch the host slice pitch
*
* @return the region size in bytes
*/
static int calculateBufferRectSize(final PointerBuffer offset, final PointerBuffer region, long row_pitch, long slice_pitch) {
if ( !LWJGLUtil.CHECKS )
return 0;
final long x = offset.get(0);
final long y = offset.get(1);
final long z = offset.get(2);
if ( LWJGLUtil.DEBUG && (x < 0 || y < 0 || z < 0) )
throw new IllegalArgumentException("Invalid cl_mem host offset: " + x + ", " + y + ", " + z);
final long w = region.get(0);
final long h = region.get(1);
final long d = region.get(2);
if ( LWJGLUtil.DEBUG && (w < 1 || h < 1 || d < 1) )
throw new IllegalArgumentException("Invalid cl_mem rectangle region dimensions: " + w + " x " + h + " x " + d);
if ( row_pitch == 0 )
row_pitch = w;
else if ( LWJGLUtil.DEBUG && row_pitch < w )
throw new IllegalArgumentException("Invalid host row pitch specified: " + row_pitch);
if ( slice_pitch == 0 )
slice_pitch = row_pitch * h;
else if ( LWJGLUtil.DEBUG && slice_pitch < (row_pitch * h) )
throw new IllegalArgumentException("Invalid host slice pitch specified: " + slice_pitch);
return (int)((z * slice_pitch + y * row_pitch + x) + (w * h * d));
}
/**
* Calculates the number of bytes in the specified cl_mem image region.
* This implementation assumes 1 byte per element, because we cannot the
* image type.
*
* @param region the image region
* @param row_pitch the row pitch
* @param slice_pitch the slice pitch
*
* @return the region size in bytes
*/
static int calculateImageSize(final PointerBuffer region, long row_pitch, long slice_pitch) {
if ( !LWJGLUtil.CHECKS )
return 0;
final long w = region.get(0);
final long h = region.get(1);
final long d = region.get(2);
if ( LWJGLUtil.DEBUG && (w < 1 || h < 1 || d < 1) )
throw new IllegalArgumentException("Invalid cl_mem image region dimensions: " + w + " x " + h + " x " + d);
if ( row_pitch == 0 )
row_pitch = w;
else if ( LWJGLUtil.DEBUG && row_pitch < w )
throw new IllegalArgumentException("Invalid row pitch specified: " + row_pitch);
if ( slice_pitch == 0 )
slice_pitch = row_pitch * h;
else if ( LWJGLUtil.DEBUG && slice_pitch < (row_pitch * h) )
throw new IllegalArgumentException("Invalid slice pitch specified: " + slice_pitch);
return (int)(slice_pitch * d);
}
/**
* Calculates the number of bytes in the specified 2D image.
*
* @param format the cl_image_format struct
* @param w the image width
* @param h the image height
* @param row_pitch the image row pitch
*
* @return the 2D image size in bytes
*/
static int calculateImage2DSize(final Buffer host_ptr, final ByteBuffer format, final long w, final long h, long row_pitch) {
if ( !LWJGLUtil.CHECKS )
return 0;
if ( LWJGLUtil.DEBUG && (w < 1 || h < 1) )
throw new IllegalArgumentException("Invalid 2D image dimensions: " + w + " x " + h);
final int elementSize = getElementSize(format);
if ( row_pitch == 0 )
row_pitch = w * elementSize;
else if ( LWJGLUtil.DEBUG && ((row_pitch < w * elementSize) || (row_pitch % elementSize != 0)) )
throw new IllegalArgumentException("Invalid image_row_pitch specified: " + row_pitch);
return (int)(row_pitch * h) >> BufferUtils.getElementSizeExponent(host_ptr);
}
/**
* Calculates the number of bytes in the specified 3D image.
*
* @param format the cl_image_format struct
* @param w the image width
* @param h the image height
* @param d the image depth
* @param row_pitch the image row pitch
* @param slice_pitch the image slice pitch
*
* @return the 3D image size in bytes
*/
static int calculateImage3DSize(final Buffer host_ptr, final ByteBuffer format, final long w, final long h, final long d, long row_pitch, long slice_pitch) {
if ( !LWJGLUtil.CHECKS )
return 0;
if ( LWJGLUtil.DEBUG && (w < 1 || h < 1 || d < 2) )
throw new IllegalArgumentException("Invalid 3D image dimensions: " + w + " x " + h + " x " + d);
final int elementSize = getElementSize(format);
if ( row_pitch == 0 )
row_pitch = w * elementSize;
else if ( LWJGLUtil.DEBUG && ((row_pitch < w * elementSize) || (row_pitch % elementSize != 0)) )
throw new IllegalArgumentException("Invalid image_row_pitch specified: " + row_pitch);
if ( slice_pitch == 0 )
slice_pitch = row_pitch * h;
else if ( LWJGLUtil.DEBUG && ((row_pitch < row_pitch * h) || (slice_pitch % row_pitch != 0)) )
throw new IllegalArgumentException("Invalid image_slice_pitch specified: " + row_pitch);
return (int)(slice_pitch * d) >> BufferUtils.getElementSizeExponent(host_ptr);
}
/**
* Returns the number of bytes per element for the specified image format.
*
* @param format a cl_image_format struct.
*
* @return the number of bytes per image element
*/
private static int getElementSize(final ByteBuffer format) {
final int channelOrder = format.getInt(format.position() + 0);
final int channelType = format.getInt(format.position() + 4);
return getChannelCount(channelOrder) * getChannelSize(channelType);
}
/**
* Returns the number of channels in the specified cl_channel_order.
*
* @param channelOrder the cl_channel_order
*
* @return the number of channels
*/
private static int getChannelCount(final int channelOrder) {
switch ( channelOrder ) {
case CL_R:
case CL_A:
case CL_INTENSITY:
case CL_LUMINANCE:
case CL_Rx:
return 1;
case CL_RG:
case CL_RA:
case CL_RGx:
return 2;
case CL_RGB:
case CL_RGBx:
return 3;
case CL_RGBA:
case CL_BGRA:
case CL_ARGB:
return 4;
default:
throw new IllegalArgumentException("Invalid cl_channel_order specified: " + LWJGLUtil.toHexString(channelOrder));
}
}
/**
* Returns the number of bytes in the specified cl_channel_type.
*
* @param channelType the cl_channel_type
*
* @return the number of bytes
*/
private static int getChannelSize(final int channelType) {
switch ( channelType ) {
case CL_SNORM_INT8:
case CL_UNORM_INT8:
case CL_SIGNED_INT8:
case CL_UNSIGNED_INT8:
return 1;
case CL_SNORM_INT16:
case CL_UNORM_INT16:
case CL_UNORM_SHORT_565:
case CL_UNORM_SHORT_555:
case CL_SIGNED_INT16:
case CL_UNSIGNED_INT16:
case CL_HALF_FLOAT:
return 2;
case CL_UNORM_INT_101010:
case CL_SIGNED_INT32:
case CL_UNSIGNED_INT32:
case CL_FLOAT:
return 4;
default:
throw new IllegalArgumentException("Invalid cl_channel_type specified: " + LWJGLUtil.toHexString(channelType));
}
}
}