diff --git a/runtime/mem_obj/image.cpp b/runtime/mem_obj/image.cpp index e2db9451e3..440ccca75e 100644 --- a/runtime/mem_obj/image.cpp +++ b/runtime/mem_obj/image.cpp @@ -206,6 +206,12 @@ Image *Image::create(Context *context, hostPtrToSet = const_cast(hostPtr); parentBuffer->incRefInternal(); Gmm::queryImgFromBufferParams(imgInfo, memory); + + auto bufferOffset = static_cast(parentBuffer->getOffset()); + if (bufferOffset != 0) { + imgInfo.offset = bufferOffset; + } + if (memoryManager->peekVirtualPaddingSupport() && (imageDesc->image_type == CL_MEM_OBJECT_IMAGE2D)) { // Retrieve sizes from GMM and apply virtual padding if buffer storage is not big enough auto queryGmmImgInfo(imgInfo); diff --git a/unit_tests/mem_obj/CMakeLists.txt b/unit_tests/mem_obj/CMakeLists.txt index 3c53c007d3..55254b1d9d 100644 --- a/unit_tests/mem_obj/CMakeLists.txt +++ b/unit_tests/mem_obj/CMakeLists.txt @@ -27,6 +27,7 @@ set(IGDRCL_SRCS_tests_mem_obj ${CMAKE_CURRENT_SOURCE_DIR}/destructor_callback_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/get_mem_object_info_subbufer_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/get_mem_object_info_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/image_from_subbuffer_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/image1d_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/image2d_from_buffer_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/image2d_tests.cpp diff --git a/unit_tests/mem_obj/image_from_subbuffer_tests.cpp b/unit_tests/mem_obj/image_from_subbuffer_tests.cpp new file mode 100644 index 0000000000..b39b36dc84 --- /dev/null +++ b/unit_tests/mem_obj/image_from_subbuffer_tests.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2018, Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "runtime/mem_obj/image.h" +#include "runtime/mem_obj/buffer.h" +#include "runtime/helpers/aligned_memory.h" +#include "unit_tests/fixtures/device_fixture.h" +#include "unit_tests/mocks/mock_context.h" +#include "test.h" + +#include +using namespace OCLRT; + +// Tests for cl_khr_image2d_from_buffer +class ImageFromSubBufferTest : public DeviceFixture, public ::testing::Test { + public: + ImageFromSubBufferTest() {} + + protected: + void SetUp() override { + imageFormat.image_channel_data_type = CL_UNORM_INT8; + imageFormat.image_channel_order = CL_RGBA; + + imageDesc.image_array_size = 0; + imageDesc.image_depth = 0; + imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D; + imageDesc.image_height = 128 / 2; + imageDesc.image_width = 256 / 2; + imageDesc.num_mip_levels = 0; + imageDesc.image_row_pitch = 0; + imageDesc.image_slice_pitch = 0; + imageDesc.num_samples = 0; + + size = 128 * 256 * 4; + hostPtr = alignedMalloc(size, 16); + ASSERT_NE(nullptr, hostPtr); + + parentBuffer = clCreateBuffer(&context, CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE, size, hostPtr, &retVal); + ASSERT_EQ(CL_SUCCESS, retVal); + + const cl_buffer_region region = {size / 2, size / 2}; + + subBuffer = clCreateSubBuffer(parentBuffer, CL_MEM_READ_WRITE, CL_BUFFER_CREATE_TYPE_REGION, + reinterpret_cast(®ion), &retVal); + ASSERT_EQ(CL_SUCCESS, retVal); + + imageDesc.mem_object = subBuffer; + ASSERT_NE(nullptr, imageDesc.mem_object); + } + void TearDown() override { + clReleaseMemObject(subBuffer); + clReleaseMemObject(parentBuffer); + alignedFree(hostPtr); + } + + Image *createImage() { + cl_mem_flags flags = CL_MEM_READ_ONLY; + auto surfaceFormat = (SurfaceFormatInfo *)Image::getSurfaceFormatFromTable(flags, &imageFormat); + return Image::create(&context, flags, surfaceFormat, &imageDesc, NULL, retVal); + } + cl_image_format imageFormat; + cl_image_desc imageDesc; + cl_int retVal = CL_SUCCESS; + MockContext context; + void *hostPtr; + size_t size; + cl_mem parentBuffer; + cl_mem subBuffer; +}; + +TEST_F(ImageFromSubBufferTest, CreateImage2dFromSubBufferWithOffset) { + std::unique_ptr imageFromSubBuffer(createImage()); + EXPECT_NE(nullptr, imageFromSubBuffer); + + SurfaceOffsets surfaceOffsets = {0}; + imageFromSubBuffer->getSurfaceOffsets(surfaceOffsets); + + uint32_t offsetExpected = static_cast(size) / 2; + + EXPECT_EQ(offsetExpected, surfaceOffsets.offset); + EXPECT_EQ(0u, surfaceOffsets.xOffset); + EXPECT_EQ(0u, surfaceOffsets.yOffset); + EXPECT_EQ(0u, surfaceOffsets.yOffsetForUVplane); +}