Validate D3D sharing formats

Related-To: NEO-5486

Signed-off-by: Mateusz Hoppe <mateusz.hoppe@intel.com>
This commit is contained in:
Mateusz Hoppe
2021-02-02 22:38:30 +01:00
committed by Compute-Runtime-Automation
parent 7a91ef844a
commit 51fd5c5e3a
10 changed files with 139 additions and 12 deletions

View File

@ -124,17 +124,14 @@ static const DXGI_FORMAT DXGIFormats[] = {
DXGI_FORMAT_NV12,
DXGI_FORMAT_P010,
DXGI_FORMAT_P016,
DXGI_FORMAT_420_OPAQUE,
DXGI_FORMAT_YUY2,
DXGI_FORMAT_Y210,
DXGI_FORMAT_Y216,
DXGI_FORMAT_NV11,
DXGI_FORMAT_AI44,
DXGI_FORMAT_IA44,
DXGI_FORMAT_P8,
DXGI_FORMAT_A8P8,
DXGI_FORMAT_B4G4R4A4_UNORM,
DXGI_FORMAT_P208,
DXGI_FORMAT_V208,
DXGI_FORMAT_V408,
DXGI_FORMAT_FORCE_UINT};
@ -216,6 +213,18 @@ bool D3DSharingFunctions<D3D>::checkFormatSupport(DXGI_FORMAT format, UINT *pFor
return errorCode == S_OK;
}
template <typename D3D>
cl_int D3DSharingFunctions<D3D>::validateFormatSupport(DXGI_FORMAT format, cl_mem_object_type type) {
auto &formats = retrieveTextureFormats(type, 0);
auto iter = std::find(formats.begin(), formats.end(), format);
if (iter != formats.end()) {
return CL_SUCCESS;
}
return CL_INVALID_IMAGE_FORMAT_DESCRIPTOR;
}
template <typename D3D>
std::vector<DXGI_FORMAT> &D3DSharingFunctions<D3D>::retrieveTextureFormats(cl_mem_object_type imageType, cl_uint plane) {
auto cached = textureFormatCache.find(imageType);

View File

@ -60,6 +60,10 @@ bool D3DSharingFunctions<D3DTypesHelper::D3D9>::checkFormatSupport(DXGI_FORMAT f
return false;
}
cl_int D3DSharingFunctions<D3DTypesHelper::D3D9>::validateFormatSupport(DXGI_FORMAT format, cl_mem_object_type type) {
return CL_SUCCESS;
}
template <>
bool D3DSharingFunctions<D3DTypesHelper::D3D9>::memObjectFormatSupport(cl_mem_object_type object, UINT format) {
return false;

View File

@ -120,6 +120,8 @@ class D3DSharingFunctions : public SharingFunctions {
MOCKABLE_VIRTUAL bool checkFormatSupport(DXGI_FORMAT format, UINT *pFormat);
MOCKABLE_VIRTUAL bool memObjectFormatSupport(cl_mem_object_type object, UINT format);
MOCKABLE_VIRTUAL cl_int validateFormatSupport(DXGI_FORMAT format, cl_mem_object_type type);
GetDxgiDescFcn getDxgiDescFcn = nullptr;
bool isTracked(D3DResource *resource, cl_uint subresource) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
* Copyright (C) 2017-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -107,6 +107,9 @@ bool D3DSharing<D3D>::isFormatWithPlane1(DXGI_FORMAT format) {
case DXGI_FORMAT_NV12:
case DXGI_FORMAT_P010:
case DXGI_FORMAT_P016:
case DXGI_FORMAT_420_OPAQUE:
case DXGI_FORMAT_NV11:
case DXGI_FORMAT_P208:
return true;
}
return false;

View File

@ -1,13 +1,11 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
* Copyright (C) 2017-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "opencl/source/sharings/d3d/d3d_sharing.h"
#include "d3d_sharing_functions.h"
enum GMM_RESOURCE_FORMAT_ENUM;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2017-2020 Intel Corporation
* Copyright (C) 2017-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -39,7 +39,13 @@ Image *D3DTexture<D3D>::create2d(Context *context, D3DTexture2d *d3dTexture, cl_
D3DTexture2dDesc textureDesc = {};
sharingFcns->getTexture2dDesc(&textureDesc, d3dTexture);
if ((textureDesc.Format == DXGI_FORMAT_NV12) || (textureDesc.Format == DXGI_FORMAT_P010) || (textureDesc.Format == DXGI_FORMAT_P016)) {
cl_int formatSupportError = sharingFcns->validateFormatSupport(textureDesc.Format, CL_MEM_OBJECT_IMAGE2D);
if (formatSupportError != CL_SUCCESS) {
err.set(formatSupportError);
return nullptr;
}
if (D3DSharing<D3D>::isFormatWithPlane1(textureDesc.Format)) {
if ((subresource % 2) == 0) {
imagePlane = ImagePlane::PLANE_Y;
} else {
@ -133,6 +139,12 @@ Image *D3DTexture<D3D>::create3d(Context *context, D3DTexture3d *d3dTexture, cl_
D3DTexture3dDesc textureDesc = {};
sharingFcns->getTexture3dDesc(&textureDesc, d3dTexture);
cl_int formatSupportError = sharingFcns->validateFormatSupport(textureDesc.Format, CL_MEM_OBJECT_IMAGE3D);
if (formatSupportError != CL_SUCCESS) {
err.set(formatSupportError);
return nullptr;
}
if (subresource >= textureDesc.MipLevels) {
err.set(CL_INVALID_VALUE);
return nullptr;

View File

@ -180,7 +180,7 @@ TEST_F(clIntelSharingFormatQueryDX10, givenInvalidContextWhenDX10TextureFormatsR
EXPECT_EQ(CL_INVALID_CONTEXT, retVal);
}
TEST_F(clIntelSharingFormatQueryDX10, givenValidParametersWhenRequestedDX10TextureFormatsThenTheResultIsASubsetOfKnownFormats) {
TEST_F(clIntelSharingFormatQueryDX10, givenValidParametersWhenRequestedDX10TextureFormatsThenTheResultIsASubsetOfKnownFormatsWithoutUnsupportedPlanars) {
retVal = clGetSupportedD3D10TextureFormatsINTEL(context, CL_MEM_READ_WRITE, CL_MEM_OBJECT_IMAGE2D,
static_cast<cl_uint>(retrievedFormats.size()),
&retrievedFormats[0], &numImageFormats);
@ -191,6 +191,10 @@ TEST_F(clIntelSharingFormatQueryDX10, givenValidParametersWhenRequestedDX10Textu
retrievedFormats[i]),
availableFormats.end());
}
EXPECT_EQ(std::find(retrievedFormats.begin(), retrievedFormats.end(), DXGI_FORMAT_420_OPAQUE), retrievedFormats.end());
EXPECT_EQ(std::find(retrievedFormats.begin(), retrievedFormats.end(), DXGI_FORMAT_NV11), retrievedFormats.end());
EXPECT_EQ(std::find(retrievedFormats.begin(), retrievedFormats.end(), DXGI_FORMAT_P208), retrievedFormats.end());
}
TEST_F(clIntelSharingFormatQueryDX10, givenValidParametersWhenRequestedDX10TextureFormatsTwiceThenTheResultsAreTheSame) {

View File

@ -595,6 +595,72 @@ TYPED_TEST_P(D3DTests, givenFormatNotSupportedByDxWhenGettingSupportedFormatsThe
EXPECT_FALSE(foundUnsupported);
}
TYPED_TEST_P(D3DTests, givenUnsupportedFormatWhenCreatingTexture2dThenInvalidImageFormatDescriptorIsReturned) {
auto checkFormat = [](DXGI_FORMAT format, UINT *pFormat) -> bool {
if (format == DXGI_FORMAT_R32_FLOAT) {
return false;
}
*pFormat = D3D11_FORMAT_SUPPORT_BUFFER | D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURE3D;
return true;
};
auto validate = [&](DXGI_FORMAT format, cl_mem_object_type type) -> cl_int {
return mockSharingFcns->validateFormatSupportBase(format, type);
};
ON_CALL(*mockSharingFcns, checkFormatSupport(::testing::_, ::testing::_)).WillByDefault(::testing::Invoke(checkFormat));
ON_CALL(*mockSharingFcns, memObjectFormatSupport(::testing::_, ::testing::_)).WillByDefault(::testing::Return(true));
ON_CALL(*mockSharingFcns, validateFormatSupport(::testing::_, ::testing::_))
.WillByDefault(::testing::Invoke(validate));
this->mockSharingFcns->mockTexture2dDesc.Format = DXGI_FORMAT_R32_FLOAT;
EXPECT_CALL(*this->mockSharingFcns, getTexture2dDesc(_, _))
.Times(1)
.WillOnce(SetArgPointee<0>(this->mockSharingFcns->mockTexture2dDesc));
cl_int retCode = CL_SUCCESS;
auto image = std::unique_ptr<Image>(D3DTexture<TypeParam>::create2d(this->context, reinterpret_cast<D3DTexture2d *>(&this->dummyD3DTexture), CL_MEM_READ_WRITE, 0, &retCode));
EXPECT_EQ(nullptr, image.get());
EXPECT_EQ(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, retCode);
}
TYPED_TEST_P(D3DTests, givenUnsupportedFormatWhenCreatingTexture3dThenInvalidImageFormatDescriptorIsReturned) {
auto checkFormat = [](DXGI_FORMAT format, UINT *pFormat) -> bool {
if (format == DXGI_FORMAT_R32_FLOAT) {
return false;
}
*pFormat = D3D11_FORMAT_SUPPORT_BUFFER | D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURE3D;
return true;
};
auto validate = [&](DXGI_FORMAT format, cl_mem_object_type type) -> cl_int {
return mockSharingFcns->validateFormatSupportBase(format, type);
};
ON_CALL(*mockSharingFcns, checkFormatSupport(::testing::_, ::testing::_)).WillByDefault(::testing::Invoke(checkFormat));
ON_CALL(*mockSharingFcns, memObjectFormatSupport(::testing::_, ::testing::_)).WillByDefault(::testing::Return(true));
ON_CALL(*mockSharingFcns, validateFormatSupport(::testing::_, ::testing::_))
.WillByDefault(::testing::Invoke(validate));
this->mockSharingFcns->mockTexture3dDesc.Format = DXGI_FORMAT_R32_FLOAT;
EXPECT_CALL(*this->mockSharingFcns, getTexture3dDesc(_, _))
.Times(1)
.WillOnce(SetArgPointee<0>(this->mockSharingFcns->mockTexture3dDesc));
cl_int retCode = CL_SUCCESS;
auto image = std::unique_ptr<Image>(D3DTexture<TypeParam>::create3d(this->context, reinterpret_cast<D3DTexture3d *>(&this->dummyD3DTexture), CL_MEM_READ_WRITE, 0, &retCode));
EXPECT_EQ(nullptr, image.get());
EXPECT_EQ(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, retCode);
}
REGISTER_TYPED_TEST_CASE_P(D3DTests,
givenSharedResourceBufferAndInteropUserSyncEnabledWhenReleaseIsCalledThenDontDoExplicitFinish,
givenNonSharedResourceBufferAndInteropUserSyncDisabledWhenReleaseIsCalledThenDoExplicitFinishTwice,
@ -618,7 +684,9 @@ REGISTER_TYPED_TEST_CASE_P(D3DTests,
givenSharedObjectFromInvalidContextAndNTHandleWhen3dCreatedThenReturnCorrectCode,
givenSharedObjectAndAlocationFailedWhen3dCreatedThenReturnCorrectCode,
givenSharedObjectAndNTHandleAndAllocationFailedWhen3dCreatedThenReturnCorrectCode,
givenFormatNotSupportedByDxWhenGettingSupportedFormatsThenOnlySupportedFormatsAreReturned);
givenFormatNotSupportedByDxWhenGettingSupportedFormatsThenOnlySupportedFormatsAreReturned,
givenUnsupportedFormatWhenCreatingTexture2dThenInvalidImageFormatDescriptorIsReturned,
givenUnsupportedFormatWhenCreatingTexture3dThenInvalidImageFormatDescriptorIsReturned);
INSTANTIATE_TYPED_TEST_CASE_P(D3DSharingTests, D3DTests, D3DTypes);
@ -647,4 +715,24 @@ TEST_F(D3D11Test, givenIncompatibleAdapterLuidWhenGettingDeviceIdsThenNoDevicesA
EXPECT_EQ(CL_DEVICE_NOT_FOUND, retVal);
EXPECT_EQ(0, numDevices);
}
TEST(D3D11, GivenPlanarFormatsWhenCallingIsFormatWithPlane1ThenTrueIsReturned) {
std::array<DXGI_FORMAT, 6> planarFormats = {DXGI_FORMAT_NV12, DXGI_FORMAT_P010, DXGI_FORMAT_P016,
DXGI_FORMAT_420_OPAQUE, DXGI_FORMAT_NV11, DXGI_FORMAT_P208};
for (auto format : planarFormats) {
EXPECT_TRUE(D3DSharing<D3DTypesHelper::D3D11>::isFormatWithPlane1(format));
}
}
TEST(D3D11, GivenNonPlanarFormatsWhenCallingIsFormatWithPlane1ThenFalseIsReturned) {
std::array<DXGI_FORMAT, 6> planarFormats = {DXGI_FORMAT_R32G32B32_FLOAT,
DXGI_FORMAT_R32G32B32_UINT,
DXGI_FORMAT_R32G32B32_SINT};
for (auto format : planarFormats) {
EXPECT_FALSE(D3DSharing<D3DTypesHelper::D3D11>::isFormatWithPlane1(format));
}
}
} // namespace NEO

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2020 Intel Corporation
* Copyright (C) 2019-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -102,6 +102,9 @@ class D3DTests : public PlatformFixture, public ::testing::Test {
mockMM = std::make_unique<MockMM>(*context->getDevice(0)->getExecutionEnvironment());
mockSharingFcns = new NiceMock<MockD3DSharingFunctions<T>>();
auto checkFormat = [](DXGI_FORMAT format, UINT *pFormat) -> bool { *pFormat = D3D11_FORMAT_SUPPORT_BUFFER | D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURE3D; return true; };
ON_CALL(*mockSharingFcns, checkFormatSupport(::testing::_, ::testing::_)).WillByDefault(::testing::Invoke(checkFormat));
context->setSharingFunctions(mockSharingFcns);
context->memoryManager = mockMM.get();
cmdQ = new MockCommandQueue(context, context->getDevice(0), 0);

View File

@ -58,7 +58,11 @@ class MockD3DSharingFunctions : public D3DSharingFunctions<D3D> {
MOCK_METHOD1_T(updateDevice, void(D3DResource *resource));
MOCK_METHOD2_T(checkFormatSupport, bool(DXGI_FORMAT format, UINT *pFormat));
MOCK_METHOD2_T(memObjectFormatSupport, bool(cl_mem_object_type object, UINT format));
MOCK_METHOD2_T(validateFormatSupport, cl_int(DXGI_FORMAT format, cl_mem_object_type type));
cl_int validateFormatSupportBase(DXGI_FORMAT format, cl_mem_object_type type) {
return D3DSharingFunctions<D3D>::validateFormatSupport(format, type);
}
std::vector<std::pair<D3DResource *, cl_uint>> *getTrackedResourcesVector() { return &this->trackedResources; }
D3DBufferDesc mockBufferDesc = {};