diff --git a/runtime/sharings/va/va_surface.cpp b/runtime/sharings/va/va_surface.cpp index 5a019c708e..5c72c780ca 100644 --- a/runtime/sharings/va/va_surface.cpp +++ b/runtime/sharings/va/va_surface.cpp @@ -71,8 +71,6 @@ Image *VASurface::createSharedVaSurface(Context *context, VASharingFunctions *sh imgSurfaceFormat = Image::getSurfaceFormatFromTable(flags, &imgFormat); - sharingFunctions->destroyImage(vaImage.image_id); - sharingFunctions->extGetSurfaceHandle(surface, &sharedHandle); auto alloc = memoryManager->createGraphicsAllocationFromSharedHandle(sharedHandle, false, true); @@ -88,7 +86,10 @@ Image *VASurface::createSharedVaSurface(Context *context, VASharingFunctions *sh if (plane == 1) { imgDesc.image_width /= 2; imgDesc.image_height /= 2; + imgInfo.offset = vaImage.offsets[1]; + imgInfo.yOffsetForUVPlane = static_cast(imgInfo.offset / vaImage.pitches[0]); } + sharingFunctions->destroyImage(vaImage.image_id); auto vaSurface = new VASurface(sharingFunctions, imageId, plane, surface, context->getInteropUserSyncEnabled()); diff --git a/unit_tests/sharings/va/mock_va_sharing.cpp b/unit_tests/sharings/va/mock_va_sharing.cpp index 271e62df56..7960b4717f 100644 --- a/unit_tests/sharings/va/mock_va_sharing.cpp +++ b/unit_tests/sharings/va/mock_va_sharing.cpp @@ -31,6 +31,7 @@ int vaGetLibFuncCalled = 0; int vaExtGetSurfaceHandleCalled = 0; osHandle acquiredVaHandle = 0; VAImage mockVaImage = {}; +uint16_t vaSharingFunctionsMockWidth, vaSharingFunctionsMockHeight; void VASharingFunctionsMock::initMembers() { vaDisplayIsValidPFN = mockVaDisplayIsValid; @@ -50,5 +51,7 @@ void VASharingFunctionsMock::initMembers() { mockVaImage = {}; acquiredVaHandle = 0; + vaSharingFunctionsMockWidth = 256u; + vaSharingFunctionsMockHeight = 256u; } } // namespace OCLRT diff --git a/unit_tests/sharings/va/mock_va_sharing.h b/unit_tests/sharings/va/mock_va_sharing.h index a811d5949a..6fe2cd2b95 100644 --- a/unit_tests/sharings/va/mock_va_sharing.h +++ b/unit_tests/sharings/va/mock_va_sharing.h @@ -21,6 +21,7 @@ */ #pragma once +#include "runtime/helpers/aligned_memory.h" #include "runtime/sharings/va/va_sharing.h" namespace OCLRT { @@ -33,6 +34,7 @@ extern int vaGetLibFuncCalled; extern int vaExtGetSurfaceHandleCalled; extern osHandle acquiredVaHandle; extern VAImage mockVaImage; +extern uint16_t vaSharingFunctionsMockWidth, vaSharingFunctionsMockHeight; class VASharingFunctionsMock : public VASharingFunctions { @@ -42,9 +44,16 @@ class VASharingFunctionsMock : public VASharingFunctions { }; static VAStatus mockVaDeriveImage(VADisplay vaDisplay, VASurfaceID vaSurface, VAImage *vaImage) { + uint32_t pitch; vaDeriveImageCalled++; - vaImage->height = 256u; - vaImage->width = 256u; + vaImage->height = vaSharingFunctionsMockHeight; + vaImage->width = vaSharingFunctionsMockWidth; + pitch = alignUp(vaSharingFunctionsMockWidth, 128); + vaImage->offsets[1] = alignUp(vaImage->height, 32) * pitch; + vaImage->offsets[2] = vaImage->offsets[1] + 1; + vaImage->pitches[0] = pitch; + vaImage->pitches[1] = pitch; + vaImage->pitches[2] = pitch; mockVaImage.width = vaImage->width; mockVaImage.height = vaImage->height; return (VAStatus)0; // success diff --git a/unit_tests/sharings/va/va_sharing_tests.cpp b/unit_tests/sharings/va/va_sharing_tests.cpp index fd90f62692..77dc017d34 100644 --- a/unit_tests/sharings/va/va_sharing_tests.cpp +++ b/unit_tests/sharings/va/va_sharing_tests.cpp @@ -133,6 +133,45 @@ TEST_F(VaSharingTests, givenMockVaWhenVaSurfaceIsCreatedThenMemObjectHasVaHandle delete vaSurface; } +TEST_F(VaSharingTests, givenMockVaWhenVaSurfaceIsCreatedWithNotAlignedWidthAndHeightThenSurfaceOffsetsUseAlignedValues) { + // this will create OS specific memory Manager + //overrideCommandStreamReceiverCreation = true; + ASSERT_FALSE(overrideCommandStreamReceiverCreation); + vaSharingFunctionsMockWidth = 256 + 16; + vaSharingFunctionsMockHeight = 512 + 16; + auto vaSurface = VASurface::createSharedVaSurface(&context, &vaSharing->m_sharingFunctions, + CL_MEM_READ_WRITE, &vaSurfaceId, 1, &errCode); + EXPECT_NE(nullptr, vaSurface); + EXPECT_NE(nullptr, vaSurface->getGraphicsAllocation()); + EXPECT_EQ(4096u, vaSurface->getGraphicsAllocation()->getUnderlyingBufferSize()); + EXPECT_EQ(1u, vaSurface->getGraphicsAllocation()->peekSharedHandle()); + + EXPECT_EQ(4096u, vaSurface->getSize()); + + auto handler = vaSurface->peekSharingHandler(); + ASSERT_NE(nullptr, handler); + + auto vaHandler = static_cast(handler); + EXPECT_EQ(vaHandler->peekFunctionsHandler(), &vaSharing->m_sharingFunctions); + + EXPECT_EQ(1u, acquiredVaHandle); + + EXPECT_EQ(1, vaDeriveImageCalled); + EXPECT_EQ(1, vaDestroyImageCalled); + EXPECT_EQ(1, vaExtGetSurfaceHandleCalled); + + SurfaceOffsets surfaceOffsets; + uint16_t alignedWidth = alignUp(vaSharingFunctionsMockWidth, 128); + uint16_t alignedHeight = alignUp(vaSharingFunctionsMockHeight, 32); + uint64_t alignedOffset = alignedWidth * alignedHeight; + + vaSurface->getSurfaceOffsets(surfaceOffsets); + EXPECT_EQ(alignedHeight, surfaceOffsets.yOffsetForUVplane); + EXPECT_EQ(alignedOffset, surfaceOffsets.offset); + + delete vaSurface; +} + TEST_F(VaSharingTests, givenContextWhenClCreateFromVaApiMediaSurfaceIsCalledThenSurfaceIsReturned) { sharedClMem = clCreateFromVA_APIMediaSurfaceINTEL(&context, CL_MEM_READ_WRITE, &vaSurfaceId, 0, &errCode); ASSERT_EQ(CL_SUCCESS, errCode);