Fix validation of size when creating image from buffer
Change-Id: Iaf9b8aae8bd3a2f2ea2b4a3d7f751dbcf4df7c0e
This commit is contained in:
parent
836e0023c1
commit
3bfbcad8c6
|
@ -444,9 +444,12 @@ cl_int Image::validate(Context *context,
|
|||
pDevice->getCap<CL_DEVICE_IMAGE_PITCH_ALIGNMENT>(reinterpret_cast<const void *&>(pitchAlignment), srcSize, retSize);
|
||||
pDevice->getCap<CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT>(reinterpret_cast<const void *&>(baseAddressAlignment), srcSize, retSize);
|
||||
|
||||
const auto rowSize = imageDesc->image_row_pitch != 0 ? imageDesc->image_row_pitch : alignUp(imageDesc->image_width * surfaceFormat->NumChannels * surfaceFormat->PerChannelSizeInBytes, *pitchAlignment);
|
||||
const auto minimumBufferSize = imageDesc->image_height * rowSize;
|
||||
|
||||
if ((imageDesc->image_row_pitch % (*pitchAlignment)) ||
|
||||
((parentBuffer->getFlags() & CL_MEM_USE_HOST_PTR) && (reinterpret_cast<uint64_t>(parentBuffer->getHostPtr()) % (*baseAddressAlignment))) ||
|
||||
(imageDesc->image_height * (imageDesc->image_row_pitch != 0 ? imageDesc->image_row_pitch : imageDesc->image_width) > parentBuffer->getSize())) {
|
||||
(minimumBufferSize > parentBuffer->getSize())) {
|
||||
return CL_INVALID_IMAGE_FORMAT_DESCRIPTOR;
|
||||
} else if (flags & (CL_MEM_USE_HOST_PTR | CL_MEM_COPY_HOST_PTR)) {
|
||||
return CL_INVALID_VALUE;
|
||||
|
@ -1299,4 +1302,4 @@ bool Image::hasValidParentImageFormat(const cl_image_format &imageFormat) const
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OCLRT
|
||||
|
|
|
@ -107,7 +107,7 @@ TEST_F(Image2dFromBufferTest, CalculateRowPitch) {
|
|||
}
|
||||
TEST_F(Image2dFromBufferTest, givenInvalidRowPitchWhenCreateImage2dFromBufferThenReturnsError) {
|
||||
char ptr[10];
|
||||
imageDesc.image_row_pitch = 257;
|
||||
imageDesc.image_row_pitch = 255;
|
||||
cl_mem_flags flags = CL_MEM_READ_ONLY;
|
||||
auto surfaceFormat = (SurfaceFormatInfo *)Image::getSurfaceFormatFromTable(flags, &imageFormat);
|
||||
retVal = Image::validate(&context, flags, surfaceFormat, &imageDesc, ptr);
|
||||
|
@ -152,10 +152,84 @@ TEST_F(Image2dFromBufferTest, InvalidFlags) {
|
|||
EXPECT_EQ(CL_INVALID_VALUE, retVal);
|
||||
}
|
||||
|
||||
TEST_F(Image2dFromBufferTest, InvalidSize) {
|
||||
imageDesc.image_height = 1024;
|
||||
TEST_F(Image2dFromBufferTest, givenOneChannel8BitColorsNoRowPitchSpecifiedAndTooLargeImageWhenValidatingSurfaceFormatThenReturnError) {
|
||||
imageDesc.image_height = 1 + castToObject<Buffer>(imageDesc.mem_object)->getSize() / imageDesc.image_width;
|
||||
cl_mem_flags flags = CL_MEM_READ_ONLY;
|
||||
auto surfaceFormat = (SurfaceFormatInfo *)Image::getSurfaceFormatFromTable(flags, &imageFormat);
|
||||
imageFormat.image_channel_data_type = CL_UNORM_INT8;
|
||||
imageFormat.image_channel_order = CL_R;
|
||||
|
||||
const auto surfaceFormat = static_cast<const SurfaceFormatInfo *>(Image::getSurfaceFormatFromTable(flags, &imageFormat));
|
||||
retVal = Image::validate(&context, flags, surfaceFormat, &imageDesc, NULL);
|
||||
EXPECT_EQ(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, retVal);
|
||||
}
|
||||
|
||||
TEST_F(Image2dFromBufferTest, givenOneChannel16BitColorsNoRowPitchSpecifiedAndTooLargeImageWhenValidatingSurfaceFormatThenReturnError) {
|
||||
imageDesc.image_height = 1 + castToObject<Buffer>(imageDesc.mem_object)->getSize() / imageDesc.image_width / 2;
|
||||
cl_mem_flags flags = CL_MEM_READ_ONLY;
|
||||
imageFormat.image_channel_data_type = CL_UNORM_INT16;
|
||||
imageFormat.image_channel_order = CL_R;
|
||||
|
||||
const auto surfaceFormat = static_cast<const SurfaceFormatInfo *>(Image::getSurfaceFormatFromTable(flags, &imageFormat));
|
||||
retVal = Image::validate(&context, flags, surfaceFormat, &imageDesc, NULL);
|
||||
EXPECT_EQ(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, retVal);
|
||||
}
|
||||
|
||||
TEST_F(Image2dFromBufferTest, givenFourChannel8BitColorsNoRowPitchSpecifiedAndTooLargeImageWhenValidatingSurfaceFormatThenReturnError) {
|
||||
imageDesc.image_height = 1 + castToObject<Buffer>(imageDesc.mem_object)->getSize() / imageDesc.image_width / 4;
|
||||
cl_mem_flags flags = CL_MEM_READ_ONLY;
|
||||
imageFormat.image_channel_data_type = CL_UNORM_INT8;
|
||||
imageFormat.image_channel_order = CL_RGBA;
|
||||
|
||||
const auto surfaceFormat = static_cast<const SurfaceFormatInfo *>(Image::getSurfaceFormatFromTable(flags, &imageFormat));
|
||||
retVal = Image::validate(&context, flags, surfaceFormat, &imageDesc, NULL);
|
||||
EXPECT_EQ(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, retVal);
|
||||
}
|
||||
|
||||
TEST_F(Image2dFromBufferTest, givenFourChannel16BitColorsNoRowPitchSpecifiedAndTooLargeImageWhenValidatingSurfaceFormatThenReturnError) {
|
||||
imageDesc.image_height = 1 + castToObject<Buffer>(imageDesc.mem_object)->getSize() / imageDesc.image_width / 8;
|
||||
cl_mem_flags flags = CL_MEM_READ_ONLY;
|
||||
imageFormat.image_channel_data_type = CL_UNORM_INT16;
|
||||
imageFormat.image_channel_order = CL_RGBA;
|
||||
|
||||
const auto surfaceFormat = static_cast<const SurfaceFormatInfo *>(Image::getSurfaceFormatFromTable(flags, &imageFormat));
|
||||
retVal = Image::validate(&context, flags, surfaceFormat, &imageDesc, NULL);
|
||||
EXPECT_EQ(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, retVal);
|
||||
}
|
||||
|
||||
TEST_F(Image2dFromBufferTest, givenFourChannel8BitColorsAndNotTooLargeRowPitchSpecifiedWhenValidatingSurfaceFormatThenDoNotReturnError) {
|
||||
imageDesc.image_height = castToObject<Buffer>(imageDesc.mem_object)->getSize() / imageDesc.image_width;
|
||||
imageDesc.image_row_pitch = imageDesc.image_width;
|
||||
cl_mem_flags flags = CL_MEM_READ_ONLY;
|
||||
imageFormat.image_channel_data_type = CL_UNORM_INT8;
|
||||
imageFormat.image_channel_order = CL_RGBA;
|
||||
|
||||
const auto surfaceFormat = static_cast<const SurfaceFormatInfo *>(Image::getSurfaceFormatFromTable(flags, &imageFormat));
|
||||
retVal = Image::validate(&context, flags, surfaceFormat, &imageDesc, NULL);
|
||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||
}
|
||||
|
||||
TEST_F(Image2dFromBufferTest, givenFourChannel8BitColorsAndTooLargeRowPitchSpecifiedWhenValidatingSurfaceFormatThenReturnError) {
|
||||
const auto pitchAlignment = &DeviceInfoTable::Map<CL_DEVICE_IMAGE_PITCH_ALIGNMENT>::getValue(context.getDevice(0u)->getDeviceInfo());
|
||||
imageDesc.image_height = castToObject<Buffer>(imageDesc.mem_object)->getSize() / imageDesc.image_width;
|
||||
imageDesc.image_row_pitch = imageDesc.image_width + *pitchAlignment;
|
||||
cl_mem_flags flags = CL_MEM_READ_ONLY;
|
||||
imageFormat.image_channel_data_type = CL_UNORM_INT8;
|
||||
imageFormat.image_channel_order = CL_RGBA;
|
||||
|
||||
const auto surfaceFormat = static_cast<const SurfaceFormatInfo *>(Image::getSurfaceFormatFromTable(flags, &imageFormat));
|
||||
retVal = Image::validate(&context, flags, surfaceFormat, &imageDesc, NULL);
|
||||
EXPECT_EQ(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, retVal);
|
||||
}
|
||||
|
||||
TEST_F(Image2dFromBufferTest, givenUnalignedImageWidthAndNoSpaceInBufferForAlignmentWhenValidatingSurfaceFormatThenReturnError) {
|
||||
context.getDevice(0u)->getMutableDeviceInfo()->imagePitchAlignment = 128;
|
||||
imageDesc.image_width = 64;
|
||||
imageDesc.image_height = castToObject<Buffer>(imageDesc.mem_object)->getSize() / imageDesc.image_width;
|
||||
cl_mem_flags flags = CL_MEM_READ_ONLY;
|
||||
imageFormat.image_channel_data_type = CL_UNORM_INT8;
|
||||
imageFormat.image_channel_order = CL_R;
|
||||
|
||||
const auto surfaceFormat = static_cast<const SurfaceFormatInfo *>(Image::getSurfaceFormatFromTable(flags, &imageFormat));
|
||||
retVal = Image::validate(&context, flags, surfaceFormat, &imageDesc, NULL);
|
||||
EXPECT_EQ(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, retVal);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue