Files
compute-runtime/unit_tests/sharings/gl/gl_create_from_texture_tests.cpp
Mateusz Jablonski 395e79fee8 Add support for many GMMs in Graphics Allocation
Change-Id: I955b8dd50b502f91700c5529d0a0a291632aa157
Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
2019-03-13 15:44:45 +01:00

327 lines
13 KiB
C++

/*
* Copyright (C) 2018-2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "runtime/helpers/get_info.h"
#include "runtime/mem_obj/image.h"
#include "runtime/sharings/gl/gl_texture.h"
#include "test.h"
#include "unit_tests/libult/create_command_stream.h"
#include "unit_tests/libult/ult_command_stream_receiver.h"
#include "unit_tests/mocks/gl/mock_gl_sharing.h"
#include "unit_tests/mocks/mock_context.h"
#include "unit_tests/mocks/mock_gmm.h"
#include "gtest/gtest.h"
namespace OCLRT {
class CreateFromGlTexture : public ::testing::Test {
public:
// temp solution - we need to query size from GMM:
class TempMM : public OsAgnosticMemoryManager {
public:
TempMM() : OsAgnosticMemoryManager(false, false, *(new ExecutionEnvironment)) {
mockExecutionEnvironment.reset(&executionEnvironment);
}
GraphicsAllocation *createGraphicsAllocationFromSharedHandle(osHandle handle, bool requireSpecificBitness) override {
auto alloc = OsAgnosticMemoryManager::createGraphicsAllocationFromSharedHandle(handle, requireSpecificBitness);
if (handle == CreateFromGlTexture::mcsHandle) {
alloc->setDefaultGmm(forceMcsGmm);
} else {
alloc->setDefaultGmm(forceGmm);
}
return alloc;
}
size_t forceAllocationSize;
Gmm *forceGmm = nullptr;
Gmm *forceMcsGmm = nullptr;
std::unique_ptr<ExecutionEnvironment> mockExecutionEnvironment;
};
void SetUp() override {
imgDesc = {};
imgInfo = {};
clContext.setSharingFunctions(glSharing->sharingFunctions.release());
ASSERT_FALSE(overrideCommandStreamReceiverCreation);
clContext.setMemoryManager(&tempMM);
}
void TearDown() override {
gmm.release();
mcsGmm.release();
}
void updateImgInfoAndForceGmm() {
imgInfo = MockGmm::initImgInfo(imgDesc, 0, nullptr);
gmm = MockGmm::queryImgParams(imgInfo);
tempMM.forceAllocationSize = imgInfo.size;
tempMM.forceGmm = gmm.get();
if (glSharing->m_textureInfoOutput.globalShareHandleMCS != 0) {
cl_image_desc mcsImgDesc = {};
mcsImgDesc.image_height = 128;
mcsImgDesc.image_row_pitch = 256;
mcsImgDesc.image_width = 128;
mcsImgDesc.image_type = CL_MEM_OBJECT_IMAGE2D;
auto mcsImgInfo = MockGmm::initImgInfo(mcsImgDesc, 0, nullptr);
mcsGmm = MockGmm::queryImgParams(mcsImgInfo);
tempMM.forceMcsGmm = mcsGmm.get();
}
}
cl_image_desc imgDesc;
ImageInfo imgInfo = {0};
std::unique_ptr<Gmm> gmm;
std::unique_ptr<Gmm> mcsGmm;
TempMM tempMM;
MockContext clContext;
std::unique_ptr<MockGlSharing> glSharing = std::make_unique<MockGlSharing>();
cl_int retVal;
static const unsigned int mcsHandle = 0xFF;
};
class CreateFromGlTextureTestsWithParams : public CreateFromGlTexture,
public ::testing::WithParamInterface<unsigned int /*cl_GLenum*/> {
};
class CreateFromGlTextureTests : public CreateFromGlTexture {
};
INSTANTIATE_TEST_CASE_P(
CreateFromGlTextureTestsWithParams,
CreateFromGlTextureTestsWithParams,
testing::ValuesIn(glTextureTargets::supportedTargets));
TEST_P(CreateFromGlTextureTestsWithParams, givenAllTextureSpecificParamsWhenCreateIsCalledThenFillImageDescription) {
unsigned int target = GetParam();
unsigned int baseTarget = GlTexture::getBaseTargetType(target);
imgDesc.image_type = GlTexture::getClMemObjectType(target);
imgDesc.image_width = 5;
if (target == GL_TEXTURE_1D_ARRAY || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
imgDesc.image_array_size = 5;
}
if (target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE ||
target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D ||
target == GL_RENDERBUFFER_EXT || baseTarget == GL_TEXTURE_CUBE_MAP_ARB ||
target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
imgDesc.image_height = 5;
}
if (target == GL_TEXTURE_3D) {
imgDesc.image_depth = 5;
}
if (target == GL_TEXTURE_BUFFER) {
// size and width for texture buffer are queried from textureInfo - not from gmm
glSharing->m_textureInfoOutput.textureBufferWidth = 64;
glSharing->m_textureInfoOutput.textureBufferSize = 1024;
glSharing->uploadDataToTextureInfo();
}
if (target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
imgDesc.num_samples = 16;
glSharing->m_textureInfoOutput.numberOfSamples = 16;
glSharing->m_textureInfoOutput.globalShareHandleMCS = CreateFromGlTexture::mcsHandle;
glSharing->uploadDataToTextureInfo();
}
updateImgInfoAndForceGmm();
auto glImage = GlTexture::createSharedGlTexture(&clContext, (cl_mem_flags)0, target, 0, 0, &retVal);
ASSERT_EQ(CL_SUCCESS, retVal);
if (target == GL_RENDERBUFFER_EXT) {
EXPECT_EQ(1, glSharing->dllParam->getParam("GLAcquireSharedRenderBufferCalled"));
} else {
EXPECT_EQ(1, glSharing->dllParam->getParam("GLAcquireSharedTextureCalled"));
}
EXPECT_EQ(GmmHelper::getCubeFaceIndex(target), glImage->getCubeFaceIndex());
auto glTexture = reinterpret_cast<GlTexture *>(glImage->peekSharingHandler());
EXPECT_EQ(glTexture->getTarget(), target);
EXPECT_EQ(glImage->getImageDesc().image_type, imgDesc.image_type);
if (target == GL_TEXTURE_BUFFER) {
EXPECT_EQ(glImage->getImageDesc().image_width,
static_cast<size_t>(glTexture->getTextureInfo()->textureBufferWidth));
EXPECT_EQ(glImage->getImageDesc().image_row_pitch,
static_cast<size_t>(glTexture->getTextureInfo()->textureBufferSize));
} else {
EXPECT_EQ(glImage->getImageDesc().image_width, gmm->gmmResourceInfo->getBaseWidth());
size_t slicePitch = glImage->getHostPtrSlicePitch();
size_t rowPitch = glImage->getHostPtrRowPitch();
EXPECT_EQ(glImage->getImageDesc().image_row_pitch, rowPitch);
EXPECT_EQ(glImage->getImageDesc().image_slice_pitch, slicePitch);
size_t gmmRowPitch = gmm->gmmResourceInfo->getRenderPitch();
if (gmmRowPitch == 0) {
size_t alignedWidth = alignUp(glImage->getImageDesc().image_width, gmm->gmmResourceInfo->getHAlign());
size_t bpp = gmm->gmmResourceInfo->getBitsPerPixel() >> 3;
EXPECT_EQ(glImage->getImageDesc().image_row_pitch, alignedWidth * bpp);
} else {
EXPECT_EQ(glImage->getImageDesc().image_row_pitch, gmmRowPitch);
}
size_t ImageInfoRowPitch = 0;
retVal = clGetImageInfo(glImage, CL_IMAGE_ROW_PITCH, sizeof(size_t), &ImageInfoRowPitch, NULL);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_EQ(rowPitch, ImageInfoRowPitch);
size_t ImageInfoSlicePitch = 0;
slicePitch *= !(glImage->getImageDesc().image_type == CL_MEM_OBJECT_IMAGE2D || glImage->getImageDesc().image_type == CL_MEM_OBJECT_IMAGE1D || glImage->getImageDesc().image_type == CL_MEM_OBJECT_IMAGE1D_BUFFER);
retVal = clGetImageInfo(glImage, CL_IMAGE_SLICE_PITCH, sizeof(size_t), &ImageInfoSlicePitch, NULL);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_EQ(slicePitch, ImageInfoSlicePitch);
}
EXPECT_EQ(glImage->getImageDesc().image_height, gmm->gmmResourceInfo->getBaseHeight());
EXPECT_EQ(glImage->getImageDesc().image_array_size, gmm->gmmResourceInfo->getArraySize());
if (target == GL_TEXTURE_3D) {
EXPECT_EQ(glImage->getImageDesc().image_depth, gmm->gmmResourceInfo->getBaseDepth());
} else {
EXPECT_EQ(glImage->getImageDesc().image_depth, 0u);
}
if (imgDesc.image_array_size > 1 || imgDesc.image_depth > 1) {
GMM_REQ_OFFSET_INFO GMMReqInfo = {};
GMMReqInfo.ArrayIndex = imgDesc.image_array_size > 1 ? 1 : 0;
GMMReqInfo.Slice = imgDesc.image_depth > 1 ? 1 : 0;
GMMReqInfo.ReqLock = 1;
gmm->gmmResourceInfo->getOffset(GMMReqInfo);
size_t expectedSlicePitch = GMMReqInfo.Lock.Offset;
EXPECT_EQ(glImage->getImageDesc().image_slice_pitch, expectedSlicePitch);
} else {
EXPECT_EQ(glImage->getImageDesc().image_slice_pitch, imgInfo.size);
}
EXPECT_EQ(glImage->getQPitch(), gmm->queryQPitch(gmm->gmmResourceInfo->getResourceType()));
// gmm returns 1 by default - OCL requires 0
uint32_t numSamples = static_cast<uint32_t>(gmm->gmmResourceInfo->getNumSamples());
auto expectedNumSamples = getValidParam(numSamples, 0u, 1u);
EXPECT_EQ(expectedNumSamples, glImage->getImageDesc().num_samples);
if (target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
EXPECT_NE(nullptr, glImage->getMcsAllocation());
EXPECT_EQ(getValidParam(static_cast<uint32_t>(mcsGmm->gmmResourceInfo->getRenderPitch() / 128)),
glImage->getMcsSurfaceInfo().pitch);
EXPECT_EQ(static_cast<uint32_t>(mcsGmm->gmmResourceInfo->getQPitch()),
glImage->getMcsSurfaceInfo().qPitch);
EXPECT_EQ(GmmHelper::getRenderMultisamplesCount(static_cast<uint32_t>(gmm->gmmResourceInfo->getNumSamples())),
glImage->getMcsSurfaceInfo().multisampleCount);
}
delete glImage;
}
TEST_P(CreateFromGlTextureTestsWithParams, givenArrayTextureTargetAndArraySizeEqualOneWhenCreateIsCalledThenSlicePitchAndSizeAreEqual) {
unsigned int target = GetParam();
// only array targets
if (target == GL_TEXTURE_1D_ARRAY ||
target == GL_TEXTURE_2D_ARRAY) {
imgDesc.image_type = GlTexture::getClMemObjectType(target);
imgDesc.image_width = 5;
if (target == GL_TEXTURE_2D_ARRAY) {
imgDesc.image_height = 5;
}
imgDesc.image_array_size = 1;
updateImgInfoAndForceGmm();
auto glImage = GlTexture::createSharedGlTexture(&clContext, (cl_mem_flags)0, target, 0, 0, &retVal);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(glImage->getImageDesc().image_slice_pitch, imgInfo.size);
delete glImage;
}
}
TEST_P(CreateFromGlTextureTestsWithParams, givenZeroRowPitchFromGmmWhenCreatingTextureThenComputeIt) {
unsigned int target = GL_TEXTURE_2D;
imgDesc.image_type = GlTexture::getClMemObjectType(target);
imgDesc.image_width = 5;
imgDesc.image_height = 5;
imgDesc.image_array_size = 1;
updateImgInfoAndForceGmm();
auto mockResInfo = reinterpret_cast<::testing::NiceMock<MockGmmResourceInfo> *>(gmm->gmmResourceInfo.get());
mockResInfo->overrideReturnedRenderPitch(0u);
auto alignedWidth = alignUp(imgDesc.image_width, gmm->gmmResourceInfo->getHAlign());
auto expectedRowPitch = alignedWidth * (gmm->gmmResourceInfo->getBitsPerPixel() >> 3);
auto glImage = std::unique_ptr<Image>(GlTexture::createSharedGlTexture(&clContext, (cl_mem_flags)0, target, 0, 0, &retVal));
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(imgInfo.size, glImage->getImageDesc().image_slice_pitch);
EXPECT_EQ(expectedRowPitch, glImage->getImageDesc().image_row_pitch);
}
TEST_F(CreateFromGlTextureTests, GivenGlTextureTargetAndMipLevelNegativeWhenCreateIsCalledThenMipMappedImageIsCreated) {
unsigned int target = GL_TEXTURE_3D;
cl_GLint miplevel = -1;
imgDesc.image_type = GlTexture::getClMemObjectType(target);
imgDesc.image_height = 13;
imgDesc.image_width = 15;
imgDesc.image_depth = 7;
updateImgInfoAndForceGmm();
auto glImage = std::unique_ptr<Image>(GlTexture::createSharedGlTexture(&clContext, 0u, target, miplevel, 0, &retVal));
EXPECT_EQ(CL_SUCCESS, retVal);
size_t actualHeight = 0;
size_t actualWidth = 0;
size_t actualDepth = 0;
glImage->getImageInfo(CL_IMAGE_HEIGHT, sizeof(size_t), &actualHeight, nullptr);
glImage->getImageInfo(CL_IMAGE_WIDTH, sizeof(size_t), &actualWidth, nullptr);
glImage->getImageInfo(CL_IMAGE_DEPTH, sizeof(size_t), &actualDepth, nullptr);
EXPECT_EQ(13u, actualHeight);
EXPECT_EQ(15u, actualWidth);
EXPECT_EQ(7u, actualDepth);
EXPECT_EQ(gmm->gmmResourceInfo->getMaxLod() + 1, glImage->getImageDesc().num_mip_levels);
EXPECT_EQ(glImage->peekBaseMipLevel(), 0);
}
TEST_F(CreateFromGlTextureTests, GivenGlTextureTargetAndMipLevelNonNegativeWhenCreateIsCalledThenImageFromChosenMipLevelIsCreated) {
unsigned int target = GL_TEXTURE_3D;
cl_GLint miplevel = 2;
imgDesc.image_type = GlTexture::getClMemObjectType(target);
imgDesc.image_height = 13;
imgDesc.image_width = 15;
imgDesc.image_depth = 7;
updateImgInfoAndForceGmm();
auto glImage = std::unique_ptr<Image>(GlTexture::createSharedGlTexture(&clContext, 0u, target, miplevel, 0, &retVal));
EXPECT_EQ(CL_SUCCESS, retVal);
size_t actualHeight = 0;
size_t actualWidth = 0;
size_t actualDepth = 0;
glImage->getImageInfo(CL_IMAGE_HEIGHT, sizeof(size_t), &actualHeight, nullptr);
glImage->getImageInfo(CL_IMAGE_WIDTH, sizeof(size_t), &actualWidth, nullptr);
glImage->getImageInfo(CL_IMAGE_DEPTH, sizeof(size_t), &actualDepth, nullptr);
EXPECT_EQ(3u, actualHeight);
EXPECT_EQ(3u, actualWidth);
EXPECT_EQ(1u, actualDepth);
EXPECT_GE(1u, glImage->getImageDesc().num_mip_levels);
EXPECT_EQ(glImage->peekBaseMipLevel(), 2);
}
} // namespace OCLRT