| // |
| // Copyright (c) 2017 The Khronos Group Inc. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| #include "utils.h" |
| |
| #include "harness/errorHelpers.h" |
| #include "harness/imageHelpers.h" |
| #include "harness/rounding_mode.h" |
| |
| #include <math.h> |
| |
| #include <CL/cl_half.h> |
| |
| static RoundingMode gFloatToHalfRoundingMode = kDefaultRoundingMode; |
| |
| |
| CResult::CResult(): |
| _result(TEST_PASS), _resultLast(TEST_NORESULT) |
| { |
| |
| } |
| |
| CResult::~CResult() |
| { |
| |
| } |
| |
| CResult::TTestResult CResult::ResultLast() const |
| { |
| return _resultLast; |
| } |
| |
| int CResult::Result() const |
| { |
| switch (_result) |
| { |
| case TEST_NORESULT: |
| case TEST_NOTSUPPORTED: |
| case TEST_PASS: |
| return 0; |
| break; |
| case TEST_FAIL: |
| return 1; |
| break; |
| case TEST_ERROR: |
| return 2; |
| break; |
| default: |
| return -1; |
| break; |
| } |
| } |
| |
| void CResult::ResultSub( TTestResult result ) |
| { |
| _resultLast = result; |
| if (static_cast<int>(result) > static_cast<int>(_result)) |
| _result = result; |
| } |
| |
| void FunctionContextCreateToString(TContextFuncType contextCreateFunction, std::string &contextFunction) |
| { |
| switch(contextCreateFunction) |
| { |
| case CONTEXT_CREATE_DEFAULT: |
| contextFunction = "CreateContext"; |
| break; |
| case CONTEXT_CREATE_FROM_TYPE: |
| contextFunction = "CreateContextFromType"; |
| break; |
| default: |
| contextFunction = "Unknown"; |
| log_error("FunctionContextCreateToString(): Unknown create function enum!"); |
| break; |
| } |
| } |
| |
| void AdapterToString(cl_dx9_media_adapter_type_khr adapterType, std::string &adapter) |
| { |
| switch(adapterType) |
| { |
| case CL_ADAPTER_D3D9_KHR: |
| adapter = "D3D9"; |
| break; |
| case CL_ADAPTER_D3D9EX_KHR: |
| adapter = "D3D9EX"; |
| break; |
| case CL_ADAPTER_DXVA_KHR: |
| adapter = "DXVA"; |
| break; |
| default: |
| adapter = "Unknown"; |
| log_error("AdapterToString(): Unknown adapter type!"); |
| break; |
| } |
| } |
| |
| cl_context_info AdapterTypeToContextInfo( cl_dx9_media_adapter_type_khr adapterType ) |
| { |
| switch (adapterType) |
| { |
| case CL_ADAPTER_D3D9_KHR: |
| return CL_CONTEXT_ADAPTER_D3D9_KHR; |
| break; |
| case CL_ADAPTER_D3D9EX_KHR: |
| return CL_CONTEXT_ADAPTER_D3D9EX_KHR; |
| break; |
| case CL_ADAPTER_DXVA_KHR: |
| return CL_CONTEXT_ADAPTER_DXVA_KHR; |
| break; |
| default: |
| log_error("AdapterTypeToContextInfo(): Unknown adapter type!"); |
| return 0; |
| break; |
| } |
| } |
| |
| void YUVGenerateNV12( std::vector<cl_uchar> &yuv, unsigned int width, unsigned int height, |
| cl_uchar valueMin, cl_uchar valueMax, double valueAdd ) |
| { |
| yuv.clear(); |
| yuv.resize(width * height * 3 / 2, 0); |
| |
| double min = static_cast<double>(valueMin); |
| double max = static_cast<double>(valueMax); |
| double range = 255; |
| double add = static_cast<double>(valueAdd * range); |
| double stepX = (max - min) / static_cast<double>(width); |
| double stepY = (max - min) /static_cast<double>(height); |
| |
| //generate Y plane |
| for (unsigned int i = 0; i < height; ++i) |
| { |
| unsigned int offset = i * width; |
| double valueYPlane0 = static_cast<double>(stepY * i); |
| for (unsigned int j = 0; j < width; ++j) |
| { |
| double valueXPlane0 = static_cast<double>(stepX * j); |
| yuv.at(offset + j) = static_cast<cl_uchar>(min + valueXPlane0 / 2 + valueYPlane0 / 2 + add); |
| } |
| } |
| |
| //generate UV planes |
| for (unsigned int i = 0; i < height / 2; ++i) |
| { |
| unsigned int offset = width * height + i * width; |
| double valueYPlane1 = static_cast<double>(stepY * i); |
| double valueYPlane2 = static_cast<double>(stepY * (height / 2 + i)); |
| for (unsigned int j = 0; j < width / 2; ++j) |
| { |
| double valueXPlane1 = static_cast<double>(stepX * j); |
| double valueXPlane2 = static_cast<double>(stepX * (width / 2 + j)); |
| |
| yuv.at(offset + j * 2) = static_cast<cl_uchar>(min + valueXPlane1 / 2 + valueYPlane1 / 2 + add); |
| yuv.at(offset + j * 2 + 1) = static_cast<cl_uchar>(min + valueXPlane2 / 2 + valueYPlane2 / 2 + add); |
| } |
| } |
| } |
| |
| void YUVGenerateYV12( std::vector<cl_uchar> &yuv, unsigned int width, unsigned int height, cl_uchar valueMin, cl_uchar valueMax, double valueAdd /*= 0.0*/ ) |
| { |
| yuv.clear(); |
| yuv.resize(width * height * 3 / 2, 0); |
| |
| double min = static_cast<double>(valueMin); |
| double max = static_cast<double>(valueMax); |
| double range = 255; |
| double add = static_cast<double>(valueAdd * range); |
| double stepX = (max - min) / static_cast<double>(width); |
| double stepY = (max - min) /static_cast<double>(height); |
| |
| unsigned offset = 0; |
| |
| //generate Y plane |
| for (unsigned int i = 0; i < height; ++i) |
| { |
| unsigned int plane0Offset = offset + i * width; |
| double valueYPlane0 = static_cast<double>(stepY * i); |
| for (unsigned int j = 0; j < width; ++j) |
| { |
| double valueXPlane0 = static_cast<double>(stepX * j); |
| yuv.at(plane0Offset + j) = static_cast<cl_uchar>(min + valueXPlane0 / 2 + valueYPlane0 / 2 + add); |
| } |
| } |
| |
| //generate V plane |
| offset += width * height; |
| for (unsigned int i = 0; i < height / 2; ++i) |
| { |
| unsigned int plane1Offset = offset + i * width / 2; |
| double valueYPlane1 = static_cast<double>(stepY * i); |
| for (unsigned int j = 0; j < width / 2; ++j) |
| { |
| double valueXPlane1 = static_cast<double>(stepX * j); |
| yuv.at(plane1Offset + j) = static_cast<cl_uchar>(min + valueXPlane1 / 2 + valueYPlane1 / 2 + add); |
| } |
| } |
| |
| //generate U plane |
| offset += width * height / 4; |
| for (unsigned int i = 0; i < height / 2; ++i) |
| { |
| unsigned int plane2Offset = offset + i * width / 2; |
| double valueYPlane2 = static_cast<double>(stepY * (height / 2 + i)); |
| for (unsigned int j = 0; j < width / 2; ++j) |
| { |
| double valueXPlane2 = static_cast<double>(stepX * j); |
| yuv.at(plane2Offset + j) = static_cast<cl_uchar>(min + valueXPlane2 / 2 + valueYPlane2 / 2 + add); |
| } |
| } |
| } |
| |
| |
| bool YUVGenerate( TSurfaceFormat surfaceFormat, std::vector<cl_uchar> &yuv, unsigned int width, unsigned int height, cl_uchar valueMin, cl_uchar valueMax, double valueAdd /*= 0.0*/ ) |
| { |
| switch (surfaceFormat) |
| { |
| case SURFACE_FORMAT_NV12: |
| YUVGenerateNV12(yuv, width, height, valueMin, valueMax, valueAdd); |
| break; |
| case SURFACE_FORMAT_YV12: |
| YUVGenerateYV12(yuv, width, height, valueMin, valueMax, valueAdd); |
| break; |
| default: |
| log_error("YUVGenerate(): Invalid surface type\n"); |
| return false; |
| break; |
| } |
| |
| return true; |
| } |
| |
| bool YUVSurfaceSetNV12( std::auto_ptr<CSurfaceWrapper> &surface, const std::vector<cl_uchar> &yuv, |
| unsigned int width, unsigned int height ) |
| { |
| #if defined(_WIN32) |
| CD3D9SurfaceWrapper *d3dSurface = static_cast<CD3D9SurfaceWrapper *>(surface.get()); |
| D3DLOCKED_RECT rect; |
| if (FAILED((*d3dSurface)->LockRect(&rect, NULL, 0))) |
| { |
| log_error("YUVSurfaceSetNV12(): Surface lock failed\n"); |
| return false; |
| } |
| |
| size_t pitch = rect.Pitch / sizeof(cl_uchar); |
| size_t lineSize = width * sizeof(cl_uchar); |
| cl_uchar *ptr = static_cast<cl_uchar *>(rect.pBits); |
| for (size_t y = 0; y < height; ++y) |
| memcpy(ptr + y * pitch, &yuv.at(y * width), lineSize); |
| |
| for (size_t y = 0; y < height / 2; ++y) |
| memcpy(ptr + height * pitch + y * pitch, &yuv.at(width * height + y * width), lineSize); |
| |
| (*d3dSurface)->UnlockRect(); |
| |
| return true; |
| |
| #else |
| return false; |
| #endif |
| } |
| |
| bool YUVSurfaceSetYV12( std::auto_ptr<CSurfaceWrapper> &surface, const std::vector<cl_uchar> &yuv, |
| unsigned int width, unsigned int height ) |
| { |
| #if defined(_WIN32) |
| CD3D9SurfaceWrapper *d3dSurface = static_cast<CD3D9SurfaceWrapper *>(surface.get()); |
| D3DLOCKED_RECT rect; |
| if (FAILED((*d3dSurface)->LockRect(&rect, NULL, 0))) |
| { |
| log_error("YUVSurfaceSetYV12(): Surface lock failed!\n"); |
| return false; |
| } |
| |
| size_t pitch = rect.Pitch / sizeof(cl_uchar); |
| size_t pitchHalf = pitch / 2; |
| size_t lineSize = width * sizeof(cl_uchar); |
| size_t lineHalfSize = lineSize / 2; |
| size_t surfaceOffset = 0; |
| size_t yuvOffset = 0; |
| cl_uchar *ptr = static_cast<cl_uchar *>(rect.pBits); |
| |
| for (size_t y = 0; y < height; ++y) |
| memcpy(ptr + surfaceOffset + y * pitch, &yuv.at(yuvOffset + y * width), lineSize); |
| |
| surfaceOffset += height * pitch; |
| yuvOffset += width * height; |
| for (size_t y = 0; y < height / 2; ++y) |
| memcpy(ptr + surfaceOffset + y * pitchHalf, &yuv.at(yuvOffset + y * lineHalfSize), lineHalfSize); |
| |
| surfaceOffset += pitchHalf * height / 2; |
| yuvOffset += width * height / 4; |
| for (size_t y = 0; y < height / 2; ++y) |
| memcpy(ptr + surfaceOffset + y * pitchHalf, &yuv.at(yuvOffset + y * lineHalfSize), lineHalfSize); |
| |
| (*d3dSurface)->UnlockRect(); |
| |
| return true; |
| |
| #else |
| return false; |
| #endif |
| } |
| |
| bool YUVSurfaceSet(TSurfaceFormat surfaceFormat, std::auto_ptr<CSurfaceWrapper> &surface, const std::vector<cl_uchar> &yuv, unsigned int width, unsigned int height ) |
| { |
| switch (surfaceFormat) |
| { |
| case SURFACE_FORMAT_NV12: |
| if(!YUVSurfaceSetNV12(surface, yuv, width, height)) |
| return false; |
| break; |
| case SURFACE_FORMAT_YV12: |
| if(!YUVSurfaceSetYV12(surface, yuv, width, height)) |
| return false; |
| break; |
| default: |
| log_error("YUVSurfaceSet(): Invalid surface type!\n"); |
| return false; |
| break; |
| } |
| |
| return true; |
| } |
| |
| bool YUVSurfaceGetNV12( std::auto_ptr<CSurfaceWrapper> &surface, std::vector<cl_uchar> &yuv, |
| unsigned int width, unsigned int height ) |
| { |
| #if defined(_WIN32) |
| CD3D9SurfaceWrapper *d3dSurface = static_cast<CD3D9SurfaceWrapper *>(surface.get()); |
| D3DLOCKED_RECT rect; |
| if (FAILED((*d3dSurface)->LockRect(&rect, NULL, 0))) |
| { |
| log_error("YUVSurfaceGetNV12(): Surface lock failed!\n"); |
| return false; |
| } |
| |
| size_t pitch = rect.Pitch / sizeof(cl_uchar); |
| size_t lineSize = width * sizeof(cl_uchar); |
| cl_uchar *ptr = static_cast<cl_uchar *>(rect.pBits); |
| size_t yuvOffset = 0; |
| size_t surfaceOffset = 0; |
| for (size_t y = 0; y < height; ++y) |
| memcpy(&yuv.at(yuvOffset + y * width), ptr + y * pitch, lineSize); |
| |
| yuvOffset += width * height; |
| surfaceOffset += pitch * height; |
| for (size_t y = 0; y < height / 2; ++y) |
| memcpy(&yuv.at(yuvOffset + y * width), ptr + surfaceOffset + y * pitch, lineSize); |
| |
| (*d3dSurface)->UnlockRect(); |
| |
| return true; |
| |
| #else |
| return false; |
| #endif |
| } |
| |
| bool YUVSurfaceGetYV12( std::auto_ptr<CSurfaceWrapper> &surface, std::vector<cl_uchar> &yuv, unsigned int width, unsigned int height ) |
| { |
| #if defined(_WIN32) |
| CD3D9SurfaceWrapper *d3dSurface = static_cast<CD3D9SurfaceWrapper *>(surface.get()); |
| D3DLOCKED_RECT rect; |
| if (FAILED((*d3dSurface)->LockRect(&rect, NULL, 0))) |
| { |
| log_error("YUVSurfaceGetYV12(): Surface lock failed!\n"); |
| return false; |
| } |
| |
| size_t pitch = rect.Pitch / sizeof(cl_uchar); |
| size_t pitchHalf = pitch / 2; |
| size_t lineSize = width * sizeof(cl_uchar); |
| size_t lineHalfSize = lineSize / 2; |
| size_t surfaceOffset = 0; |
| size_t yuvOffset = 0; |
| cl_uchar *ptr = static_cast<cl_uchar *>(rect.pBits); |
| |
| for (size_t y = 0; y < height; ++y) |
| memcpy(&yuv.at(yuvOffset + y * width), ptr + surfaceOffset + y * pitch, lineSize); |
| |
| surfaceOffset += pitch * height; |
| yuvOffset += width * height; |
| for (size_t y = 0; y < height / 2; ++y) |
| memcpy(&yuv.at(yuvOffset + y * lineHalfSize), ptr + surfaceOffset + y * pitchHalf, lineHalfSize); |
| |
| surfaceOffset += pitchHalf * height / 2; |
| yuvOffset += width * height / 4; |
| for (size_t y = 0; y < height / 2; ++y) |
| memcpy(&yuv.at(yuvOffset + y * lineHalfSize), ptr + surfaceOffset + y * pitchHalf, lineHalfSize); |
| |
| (*d3dSurface)->UnlockRect(); |
| |
| return true; |
| |
| #else |
| return false; |
| #endif |
| } |
| |
| bool YUVSurfaceGet(TSurfaceFormat surfaceFormat, std::auto_ptr<CSurfaceWrapper> &surface, std::vector<cl_uchar> &yuv, |
| unsigned int width, unsigned int height ) |
| { |
| switch (surfaceFormat) |
| { |
| case SURFACE_FORMAT_NV12: |
| if(!YUVSurfaceGetNV12(surface, yuv, width, height)) |
| return false; |
| break; |
| case SURFACE_FORMAT_YV12: |
| if(!YUVSurfaceGetYV12(surface, yuv, width, height)) |
| return false; |
| break; |
| default: |
| log_error("YUVSurfaceGet(): Invalid surface type!\n"); |
| return false; |
| break; |
| } |
| |
| return true; |
| } |
| |
| bool YUVCompareNV12( const std::vector<cl_uchar> &yuvTest, const std::vector<cl_uchar> &yuvRef, |
| unsigned int width, unsigned int height ) |
| { |
| //plane 0 verification |
| size_t offset = 0; |
| for (size_t y = 0; y < height; ++y) |
| { |
| size_t plane0Offset = offset + width * y; |
| for (size_t x = 0; x < width; ++x) |
| { |
| if (yuvTest[plane0Offset + x] != yuvRef[plane0Offset + x]) |
| { |
| log_error("Plane 0 (Y) is different than expected, reference value: %i, test value: %i, x: %i, y: %i\n", |
| yuvRef[plane0Offset + x], yuvTest[plane0Offset + x], x, y); |
| return false; |
| } |
| } |
| } |
| |
| //plane 1 and 2 verification |
| offset += width * height; |
| for (size_t y = 0; y < height / 2; ++y) |
| { |
| size_t plane12Offset = offset + width * y; |
| for (size_t x = 0; x < width / 2; ++x) |
| { |
| if (yuvTest.at(plane12Offset + 2 * x) != yuvRef.at(plane12Offset + 2 * x)) |
| { |
| log_error("Plane 1 (U) is different than expected, reference value: %i, test value: %i, x: %i, y: %i\n", |
| yuvRef[plane12Offset + 2 * x], yuvTest[plane12Offset + 2 * x], x, y); |
| return false; |
| } |
| |
| if (yuvTest.at(plane12Offset + 2 * x + 1) != yuvRef.at(plane12Offset + 2 * x + 1)) |
| { |
| log_error("Plane 2 (V) is different than expected, reference value: %i, test value: %i, x: %i, y: %i\n", |
| yuvRef[plane12Offset + 2 * x + 1], yuvTest[plane12Offset + 2 * x + 1], x, y); |
| return false; |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| bool YUVCompareYV12( const std::vector<cl_uchar> &yuvTest, const std::vector<cl_uchar> &yuvRef, |
| unsigned int width, unsigned int height ) |
| { |
| //plane 0 verification |
| size_t offset = 0; |
| for (size_t y = 0; y < height; ++y) |
| { |
| size_t plane0Offset = width * y; |
| for (size_t x = 0; x < width; ++x) |
| { |
| if (yuvTest.at(plane0Offset + x) != yuvRef.at(plane0Offset + x)) |
| { |
| log_error("Plane 0 (Y) is different than expected, reference value: %i, test value: %i, x: %i, y: %i\n", |
| yuvRef[plane0Offset + x], yuvTest[plane0Offset + x], x ,y); |
| return false; |
| } |
| } |
| } |
| |
| //plane 1 verification |
| offset += width * height; |
| for (size_t y = 0; y < height / 2; ++y) |
| { |
| size_t plane1Offset = offset + width * y / 2; |
| for (size_t x = 0; x < width / 2; ++x) |
| { |
| if (yuvTest.at(plane1Offset + x) != yuvRef.at(plane1Offset + x)) |
| { |
| log_error("Plane 1 (V) is different than expected, reference value: %i, test value: %i, x: %i, y: %i\n", |
| yuvRef[plane1Offset + x], yuvTest[plane1Offset + x], x, y); |
| return false; |
| } |
| } |
| } |
| |
| //plane 2 verification |
| offset += width * height / 4; |
| for (size_t y = 0; y < height / 2; ++y) |
| { |
| size_t plane2Offset = offset + width * y / 2; |
| for (size_t x = 0; x < width / 2; ++x) |
| { |
| if (yuvTest.at(plane2Offset + x) != yuvRef.at(plane2Offset + x)) |
| { |
| log_error("Plane 2 (U) is different than expected, reference value: %i, test value: %i, x: %i, y: %i\n", |
| yuvRef[plane2Offset + x], yuvTest[plane2Offset + x], x, y); |
| return false; |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| bool YUVCompare( TSurfaceFormat surfaceFormat, const std::vector<cl_uchar> &yuvTest, const std::vector<cl_uchar> &yuvRef, |
| unsigned int width, unsigned int height ) |
| { |
| switch (surfaceFormat) |
| { |
| case SURFACE_FORMAT_NV12: |
| if (!YUVCompareNV12(yuvTest, yuvRef, width, height)) |
| { |
| log_error("OCL object is different than expected!\n"); |
| return false; |
| } |
| break; |
| case SURFACE_FORMAT_YV12: |
| if (!YUVCompareYV12(yuvTest, yuvRef, width, height)) |
| { |
| log_error("OCL object is different than expected!\n"); |
| return false; |
| } |
| break; |
| default: |
| log_error("YUVCompare(): Invalid surface type!\n"); |
| return false; |
| break; |
| } |
| |
| return true; |
| } |
| |
| void DataGenerate( TSurfaceFormat surfaceFormat, cl_channel_type type, std::vector<float> &data, unsigned int width, unsigned int height, |
| unsigned int channelNum, float cmin /*= 0.0f*/, float cmax /*= 1.0f*/, float add /*= 0.0f*/ ) |
| { |
| data.clear(); |
| data.reserve(width * height * channelNum); |
| |
| double valueMin = static_cast<double>(cmin); |
| double valueMax = static_cast<double>(cmax); |
| double stepX = (valueMax - valueMin) / static_cast<double>(width); |
| double stepY = (valueMax - valueMin) /static_cast<double>(height); |
| double valueAdd = static_cast<double>(add); |
| for (unsigned int i = 0; i < height; ++i) |
| { |
| double valueY = static_cast<double>(stepY * i); |
| for (unsigned int j = 0; j < width; ++j) |
| { |
| double valueX = static_cast<double>(stepX * j); |
| switch (channelNum) |
| { |
| case 1: |
| data.push_back(static_cast<float>(valueMin + valueX / 2 + valueY / 2 + valueAdd)); |
| break; |
| case 2: |
| data.push_back(static_cast<float>(valueMin + valueX + valueAdd)); |
| data.push_back(static_cast<float>(valueMin + valueY + valueAdd)); |
| break; |
| case 4: |
| data.push_back(static_cast<float>(valueMin + valueX + valueAdd)); |
| data.push_back(static_cast<float>(valueMin + valueY + valueAdd)); |
| data.push_back(static_cast<float>(valueMin + valueX / 2 + valueAdd)); |
| data.push_back(static_cast<float>(valueMin + valueY / 2 + valueAdd)); |
| break; |
| default: |
| log_error("DataGenerate(): invalid channel number!"); |
| return; |
| break; |
| } |
| } |
| } |
| } |
| |
| void DataGenerate( TSurfaceFormat surfaceFormat, cl_channel_type type, std::vector<cl_half> &data, unsigned int width, unsigned int height, |
| unsigned int channelNum, float cmin /*= 0.0f*/, float cmax /*= 1.0f*/, float add /*= 0.0f*/ ) |
| { |
| data.clear(); |
| data.reserve(width * height * channelNum); |
| |
| double valueMin = static_cast<double>(cmin); |
| double valueMax = static_cast<double>(cmax); |
| double stepX = (valueMax - valueMin) / static_cast<double>(width); |
| double stepY = (valueMax - valueMin) /static_cast<double>(height); |
| |
| switch(type) |
| { |
| case CL_HALF_FLOAT: |
| { |
| double valueAdd = static_cast<double>(add); |
| |
| for (unsigned int i = 0; i < height; ++i) |
| { |
| double valueY = static_cast<double>(stepY * i); |
| for (unsigned int j = 0; j < width; ++j) |
| { |
| double valueX = static_cast<double>(stepX * j); |
| switch (channelNum) |
| { |
| case 1: |
| data.push_back(convert_float_to_half(static_cast<float>(valueMin + valueX / 2 + valueY / 2 + valueAdd))); |
| break; |
| case 2: |
| data.push_back(convert_float_to_half(static_cast<float>(valueMin + valueX + valueAdd))); |
| data.push_back(convert_float_to_half(static_cast<float>(valueMin + valueY + valueAdd))); |
| break; |
| case 4: |
| data.push_back(convert_float_to_half(static_cast<float>(valueMin + valueX + valueAdd))); |
| data.push_back(convert_float_to_half(static_cast<float>(valueMin + valueY + valueAdd))); |
| data.push_back(convert_float_to_half(static_cast<float>(valueMin + valueX / 2 + valueAdd))); |
| data.push_back(convert_float_to_half(static_cast<float>(valueMin + valueY / 2 + valueAdd))); |
| break; |
| default: |
| log_error("DataGenerate(): invalid channel number!"); |
| return; |
| break; |
| } |
| } |
| } |
| break; |
| } |
| case CL_UNORM_INT16: |
| { |
| double range = 65535; |
| double valueAdd = static_cast<double>(add * range); |
| |
| for (unsigned int i = 0; i < height; ++i) |
| { |
| double valueY = static_cast<double>(stepY * i * range); |
| for (unsigned int j = 0; j < width; ++j) |
| { |
| double valueX = static_cast<double>(stepX * j * range); |
| switch (channelNum) |
| { |
| case 1: |
| data.push_back(static_cast<cl_ushort>(valueMin + valueX / 2 + valueY / 2 + valueAdd)); |
| break; |
| case 2: |
| data.push_back(static_cast<cl_ushort>(valueMin + valueX + valueAdd)); |
| data.push_back(static_cast<cl_ushort>(valueMin + valueY + valueAdd)); |
| break; |
| case 4: |
| data.push_back(static_cast<cl_ushort>(valueMin + valueX + valueAdd)); |
| data.push_back(static_cast<cl_ushort>(valueMin + valueY + valueAdd)); |
| data.push_back(static_cast<cl_ushort>(valueMin + valueX / 2 + valueAdd)); |
| data.push_back(static_cast<cl_ushort>(valueMin + valueY / 2 + valueAdd)); |
| break; |
| default: |
| log_error("DataGenerate(): invalid channel number!"); |
| return; |
| break; |
| } |
| } |
| } |
| } |
| break; |
| default: |
| log_error("DataGenerate(): unknown data type!"); |
| return; |
| break; |
| } |
| } |
| |
| void DataGenerate( TSurfaceFormat surfaceFormat, cl_channel_type type, std::vector<cl_uchar> &data, unsigned int width, unsigned int height, |
| unsigned int channelNum, float cmin /*= 0.0f*/, float cmax /*= 1.0f*/, float add /*= 0.0f*/ ) |
| { |
| data.clear(); |
| data.reserve(width * height * channelNum); |
| |
| double valueMin = static_cast<double>(cmin); |
| double valueMax = static_cast<double>(cmax); |
| double stepX = (valueMax - valueMin) / static_cast<double>(width); |
| double stepY = (valueMax - valueMin) /static_cast<double>(height); |
| |
| double range = 255; |
| double valueAdd = static_cast<double>(add * range); |
| |
| for (unsigned int i = 0; i < height; ++i) |
| { |
| double valueY = static_cast<double>(stepY * i * range); |
| for (unsigned int j = 0; j < width; ++j) |
| { |
| double valueX = static_cast<double>(stepX * j * range); |
| switch (channelNum) |
| { |
| case 1: |
| data.push_back(static_cast<cl_uchar>(valueMin + valueX / 2 + valueY / 2 + valueAdd)); |
| break; |
| case 2: |
| data.push_back(static_cast<cl_uchar>(valueMin + valueX + valueAdd)); |
| data.push_back(static_cast<cl_uchar>(valueMin + valueY + valueAdd)); |
| break; |
| case 4: |
| data.push_back(static_cast<cl_uchar>(valueMin + valueX + valueAdd)); |
| data.push_back(static_cast<cl_uchar>(valueMin + valueY + valueAdd)); |
| data.push_back(static_cast<cl_uchar>(valueMin + valueX / 2 + valueAdd)); |
| if (surfaceFormat == SURFACE_FORMAT_X8R8G8B8) |
| data.push_back(static_cast<cl_uchar>(0xff)); |
| else |
| data.push_back(static_cast<cl_uchar>(valueMin + valueY / 2 + valueAdd)); |
| break; |
| default: |
| log_error("DataGenerate(): invalid channel number!"); |
| return; |
| break; |
| } |
| } |
| } |
| } |
| |
| bool DataCompare( TSurfaceFormat surfaceFormat, cl_channel_type type, const std::vector<float> &dataTest, const std::vector<float> &dataExp, |
| unsigned int width, unsigned int height, unsigned int channelNum) |
| { |
| float epsilon = 0.000001f; |
| for (unsigned int i = 0; i < height; ++i) |
| { |
| unsigned int offset = i * width * channelNum; |
| for (unsigned int j = 0; j < width; ++j) |
| { |
| for(unsigned planeIdx = 0; planeIdx < channelNum; ++planeIdx) |
| { |
| if (abs(dataTest.at(offset + j * channelNum + planeIdx) - dataExp.at(offset + j * channelNum + planeIdx)) > epsilon) |
| { |
| log_error("Tested image is different than reference (x,y,plane) = (%i,%i,%i), test value = %f, expected value = %f\n", |
| j, i, planeIdx, dataTest[offset + j * channelNum + planeIdx], dataExp[offset + j * channelNum + planeIdx]); |
| return false; |
| } |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| bool DataCompare( TSurfaceFormat surfaceFormat, cl_channel_type type, const std::vector<cl_half> &dataTest, const std::vector<cl_half> &dataExp, |
| unsigned int width, unsigned int height, unsigned int channelNum) |
| { |
| switch(type) |
| { |
| case CL_HALF_FLOAT: |
| { |
| float epsilon = 0.001f; |
| for (unsigned int i = 0; i < height; ++i) |
| { |
| unsigned int offset = i * width * channelNum; |
| for (unsigned int j = 0; j < width; ++j) |
| { |
| for(unsigned planeIdx = 0; planeIdx < channelNum; ++planeIdx) |
| { |
| float test = cl_half_to_float( |
| dataTest.at(offset + j * channelNum + planeIdx)); |
| float ref = cl_half_to_float( |
| dataExp.at(offset + j * channelNum + planeIdx)); |
| if (abs(test - ref) > epsilon) |
| { |
| log_error( |
| "Tested image is different than reference (x,y,plane) = " |
| "(%i,%i,%i), test value = %f, expected value = %f\n", |
| j, i, planeIdx, test, ref); |
| return false; |
| } |
| } |
| } |
| } |
| } |
| break; |
| case CL_UNORM_INT16: |
| { |
| cl_ushort epsilon = 1; |
| for (unsigned int i = 0; i < height; ++i) |
| { |
| unsigned int offset = i * width * channelNum; |
| for (unsigned int j = 0; j < width; ++j) |
| { |
| for(unsigned planeIdx = 0; planeIdx < channelNum; ++planeIdx) |
| { |
| cl_ushort test = dataTest.at(offset + j * channelNum + planeIdx); |
| cl_ushort ref = dataExp.at(offset + j * channelNum + planeIdx); |
| if (abs(test - ref) > epsilon) |
| { |
| log_error("Tested image is different than reference (x,y,plane) = (%i,%i,%i), test value = %i, expected value = %i\n", j, i, planeIdx, test, ref); |
| return false; |
| } |
| } |
| } |
| } |
| } |
| break; |
| default: |
| log_error("DataCompare(): Invalid data format!"); |
| return false; |
| break; |
| } |
| |
| return true; |
| } |
| |
| bool DataCompare( TSurfaceFormat surfaceFormat, cl_channel_type type, const std::vector<cl_uchar> &dataTest, const std::vector<cl_uchar> &dataExp, |
| unsigned int width, unsigned int height, unsigned int planeNum ) |
| { |
| for (unsigned int i = 0; i < height; ++i) |
| { |
| unsigned int offset = i * width * planeNum; |
| for (unsigned int j = 0; j < width; ++j) |
| { |
| for(unsigned planeIdx = 0; planeIdx < planeNum; ++planeIdx) |
| { |
| if (surfaceFormat == SURFACE_FORMAT_X8R8G8B8 && planeIdx == 3) |
| continue; |
| |
| cl_uchar test = dataTest.at(offset + j * planeNum + planeIdx); |
| cl_uchar ref = dataExp.at(offset + j * planeNum + planeIdx); |
| if (test != ref) |
| { |
| log_error("Tested image is different than reference (x,y,plane) = (%i,%i,%i), test value = %i, expected value = %i\n", |
| j, i, planeIdx, test, ref); |
| return false; |
| } |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| bool GetImageInfo( cl_mem object, cl_image_format formatExp, size_t elementSizeExp, size_t rowPitchExp, |
| size_t slicePitchExp, size_t widthExp, size_t heightExp, size_t depthExp , unsigned int planeExp) |
| { |
| bool result = true; |
| |
| cl_image_format format; |
| if (clGetImageInfo(object, CL_IMAGE_FORMAT, sizeof(cl_image_format), &format, 0) != CL_SUCCESS) |
| { |
| log_error("clGetImageInfo(CL_IMAGE_FORMAT) failed\n"); |
| result = false; |
| } |
| |
| if (formatExp.image_channel_order != format.image_channel_order || formatExp.image_channel_data_type != format.image_channel_data_type) |
| { |
| log_error("Value of CL_IMAGE_FORMAT is different than expected\n"); |
| result = false; |
| } |
| |
| size_t elementSize = 0; |
| if (clGetImageInfo(object, CL_IMAGE_ELEMENT_SIZE, sizeof(size_t), &elementSize, 0) != CL_SUCCESS) |
| { |
| log_error("clGetImageInfo(CL_IMAGE_ELEMENT_SIZE) failed\n"); |
| result = false; |
| } |
| |
| if (elementSizeExp != elementSize) |
| { |
| log_error("Value of CL_IMAGE_ELEMENT_SIZE is different than expected (size: %i, exp size: %i)\n", elementSize, elementSizeExp); |
| result = false; |
| } |
| |
| size_t rowPitch = 0; |
| if (clGetImageInfo(object, CL_IMAGE_ROW_PITCH, sizeof(size_t), &rowPitch, 0) != CL_SUCCESS) |
| { |
| log_error("clGetImageInfo(CL_IMAGE_ROW_PITCH) failed\n"); |
| result = false; |
| } |
| |
| if ((rowPitchExp == 0 && rowPitchExp != rowPitch) || (rowPitchExp > 0 && rowPitchExp > rowPitch)) |
| { |
| log_error("Value of CL_IMAGE_ROW_PITCH is different than expected (size: %i, exp size: %i)\n", rowPitch, rowPitchExp); |
| result = false; |
| } |
| |
| size_t slicePitch = 0; |
| if (clGetImageInfo(object, CL_IMAGE_SLICE_PITCH, sizeof(size_t), &slicePitch, 0) != CL_SUCCESS) |
| { |
| log_error("clGetImageInfo(CL_IMAGE_SLICE_PITCH) failed\n"); |
| result = false; |
| } |
| |
| if ((slicePitchExp == 0 && slicePitchExp != slicePitch) || (slicePitchExp > 0 && slicePitchExp > slicePitch)) |
| { |
| log_error("Value of CL_IMAGE_SLICE_PITCH is different than expected (size: %i, exp size: %i)\n", slicePitch, slicePitchExp); |
| result = false; |
| } |
| |
| size_t width = 0; |
| if (clGetImageInfo(object, CL_IMAGE_WIDTH, sizeof(size_t), &width, 0) != CL_SUCCESS) |
| { |
| log_error("clGetImageInfo(CL_IMAGE_WIDTH) failed\n"); |
| result = false; |
| } |
| |
| if (widthExp != width) |
| { |
| log_error("Value of CL_IMAGE_WIDTH is different than expected (size: %i, exp size: %i)\n", width, widthExp); |
| result = false; |
| } |
| |
| size_t height = 0; |
| if (clGetImageInfo(object, CL_IMAGE_HEIGHT, sizeof(size_t), &height, 0) != CL_SUCCESS) |
| { |
| log_error("clGetImageInfo(CL_IMAGE_HEIGHT) failed\n"); |
| result = false; |
| } |
| |
| if (heightExp != height) |
| { |
| log_error("Value of CL_IMAGE_HEIGHT is different than expected (size: %i, exp size: %i)\n", height, heightExp); |
| result = false; |
| } |
| |
| size_t depth = 0; |
| if (clGetImageInfo(object, CL_IMAGE_DEPTH, sizeof(size_t), &depth, 0) != CL_SUCCESS) |
| { |
| log_error("clGetImageInfo(CL_IMAGE_DEPTH) failed\n"); |
| result = false; |
| } |
| |
| if (depthExp != depth) |
| { |
| log_error("Value of CL_IMAGE_DEPTH is different than expected (size: %i, exp size: %i)\n", depth, depthExp); |
| result = false; |
| } |
| |
| unsigned int plane = 99; |
| size_t paramSize = 0; |
| if (clGetImageInfo(object, CL_IMAGE_DX9_MEDIA_PLANE_KHR, sizeof(unsigned int), &plane, ¶mSize) != CL_SUCCESS) |
| { |
| log_error("clGetImageInfo(CL_IMAGE_MEDIA_SURFACE_PLANE_KHR) failed\n"); |
| result = false; |
| } |
| |
| if (planeExp != plane) |
| { |
| log_error("Value of CL_IMAGE_MEDIA_SURFACE_PLANE_KHR is different than expected (plane: %i, exp plane: %i)\n", plane, planeExp); |
| result = false; |
| } |
| |
| return result; |
| } |
| |
| bool GetMemObjInfo( cl_mem object, cl_dx9_media_adapter_type_khr adapterType, std::auto_ptr<CSurfaceWrapper> &surface, void *shareHandleExp ) |
| { |
| bool result = true; |
| switch(adapterType) |
| { |
| case CL_ADAPTER_D3D9_KHR: |
| case CL_ADAPTER_D3D9EX_KHR: |
| case CL_ADAPTER_DXVA_KHR: |
| { |
| #if defined(_WIN32) |
| cl_dx9_surface_info_khr surfaceInfo; |
| #else |
| void *surfaceInfo = 0; |
| return false; |
| #endif |
| size_t paramSize = 0; |
| if(clGetMemObjectInfo(object, CL_MEM_DX9_MEDIA_SURFACE_INFO_KHR, sizeof(surfaceInfo), &surfaceInfo, ¶mSize) != CL_SUCCESS) |
| { |
| log_error("clGetImageInfo(CL_MEM_DX9_MEDIA_SURFACE_INFO_KHR) failed\n"); |
| result = false; |
| } |
| |
| #if defined(_WIN32) |
| CD3D9SurfaceWrapper *d3d9Surface = static_cast<CD3D9SurfaceWrapper *>(surface.get()); |
| if (*d3d9Surface != surfaceInfo.resource) |
| { |
| log_error("Invalid resource for CL_MEM_DX9_MEDIA_SURFACE_INFO_KHR\n"); |
| result = false; |
| } |
| |
| if (shareHandleExp != surfaceInfo.shared_handle) |
| { |
| log_error("Invalid shared handle for CL_MEM_DX9_MEDIA_SURFACE_INFO_KHR\n"); |
| result = false; |
| } |
| #else |
| return false; |
| #endif |
| |
| if (paramSize != sizeof(surfaceInfo)) |
| { |
| log_error("Invalid CL_MEM_DX9_MEDIA_SURFACE_INFO_KHR parameter size: %i, expected: %i\n", paramSize, sizeof(surfaceInfo)); |
| result = false; |
| } |
| |
| paramSize = 0; |
| cl_dx9_media_adapter_type_khr mediaAdapterType; |
| if(clGetMemObjectInfo(object, CL_MEM_DX9_MEDIA_ADAPTER_TYPE_KHR, sizeof(mediaAdapterType), &mediaAdapterType, ¶mSize) != CL_SUCCESS) |
| { |
| log_error("clGetImageInfo(CL_MEM_DX9_MEDIA_ADAPTER_TYPE_KHR) failed\n"); |
| result = false; |
| } |
| |
| if (adapterType != mediaAdapterType) |
| { |
| log_error("Invalid media adapter type for CL_MEM_DX9_MEDIA_ADAPTER_TYPE_KHR\n"); |
| result = false; |
| } |
| |
| if (paramSize != sizeof(mediaAdapterType)) |
| { |
| log_error("Invalid CL_MEM_DX9_MEDIA_ADAPTER_TYPE_KHR parameter size: %i, expected: %i\n", paramSize, sizeof(mediaAdapterType)); |
| result = false; |
| } |
| } |
| break; |
| default: |
| log_error("GetMemObjInfo(): Unknown adapter type!\n"); |
| return false; |
| break; |
| } |
| |
| return result; |
| } |
| |
| bool ImageInfoVerify( cl_dx9_media_adapter_type_khr adapterType, const std::vector<cl_mem> &memObjList, unsigned int width, unsigned int height, |
| std::auto_ptr<CSurfaceWrapper> &surface, void *sharedHandle) |
| { |
| if (memObjList.size() != 2 && memObjList.size() != 3) |
| { |
| log_error("ImageInfoVerify(): Invalid object list parameter\n"); |
| return false; |
| } |
| |
| cl_image_format formatPlane; |
| formatPlane.image_channel_data_type = CL_UNORM_INT8; |
| formatPlane.image_channel_order = CL_R; |
| |
| //plane 0 verification |
| if (!GetImageInfo(memObjList[0], formatPlane, sizeof(cl_uchar), |
| width * sizeof(cl_uchar), |
| 0, |
| width, height, 0, 0)) |
| { |
| log_error("clGetImageInfo failed\n"); |
| return false; |
| } |
| |
| switch (memObjList.size()) |
| { |
| case 2: |
| { |
| formatPlane.image_channel_data_type = CL_UNORM_INT8; |
| formatPlane.image_channel_order = CL_RG; |
| if (!GetImageInfo(memObjList[1], formatPlane, sizeof(cl_uchar) * 2, |
| width * sizeof(cl_uchar), |
| 0, |
| width / 2, height / 2, 0, 1)) |
| { |
| log_error("clGetImageInfo failed\n"); |
| return false; |
| } |
| } |
| break; |
| case 3: |
| { |
| if (!GetImageInfo(memObjList[1], formatPlane, sizeof(cl_uchar), |
| width * sizeof(cl_uchar) / 2, |
| 0, |
| width / 2, height / 2, 0, 1)) |
| { |
| log_error("clGetImageInfo failed\n"); |
| return false; |
| } |
| |
| if (!GetImageInfo(memObjList[2], formatPlane, sizeof(cl_uchar), |
| width * sizeof(cl_uchar) / 2, |
| 0, |
| width / 2, height / 2, 0, 2)) |
| { |
| log_error("clGetImageInfo failed\n"); |
| return false; |
| } |
| } |
| break; |
| default: |
| log_error("ImageInfoVerify(): Invalid object list parameter\n"); |
| return false; |
| break; |
| } |
| |
| for (size_t i = 0; i < memObjList.size(); ++i) |
| { |
| if (!GetMemObjInfo(memObjList[i], adapterType, surface, sharedHandle)) |
| { |
| log_error("clGetMemObjInfo(%i) failed\n", i); |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| bool ImageFormatCheck(cl_context context, cl_mem_object_type imageType, const cl_image_format imageFormatCheck) |
| { |
| cl_uint imageFormatsNum = 0; |
| cl_int error = clGetSupportedImageFormats(context, CL_MEM_READ_WRITE, imageType, 0, 0, &imageFormatsNum); |
| if(error != CL_SUCCESS) |
| { |
| log_error("clGetSupportedImageFormats failed\n"); |
| return false; |
| } |
| |
| if(imageFormatsNum < 1) |
| { |
| log_error("Invalid image format number returned by clGetSupportedImageFormats\n"); |
| return false; |
| } |
| |
| std::vector<cl_image_format> imageFormats(imageFormatsNum); |
| error = clGetSupportedImageFormats(context, CL_MEM_READ_WRITE, imageType, imageFormatsNum, &imageFormats[0], 0); |
| if(error != CL_SUCCESS) |
| { |
| log_error("clGetSupportedImageFormats failed\n"); |
| return false; |
| } |
| |
| for(cl_uint i = 0; i < imageFormatsNum; ++i) |
| { |
| if(imageFormats[i].image_channel_data_type == imageFormatCheck.image_channel_data_type |
| && imageFormats[i].image_channel_order == imageFormatCheck.image_channel_order) |
| { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| unsigned int ChannelNum( TSurfaceFormat surfaceFormat ) |
| { |
| switch(surfaceFormat) |
| { |
| case SURFACE_FORMAT_R32F: |
| case SURFACE_FORMAT_R16F: |
| case SURFACE_FORMAT_L16: |
| case SURFACE_FORMAT_A8: |
| case SURFACE_FORMAT_L8: |
| return 1; |
| break; |
| case SURFACE_FORMAT_G32R32F: |
| case SURFACE_FORMAT_G16R16F: |
| case SURFACE_FORMAT_G16R16: |
| case SURFACE_FORMAT_A8L8: |
| return 2; |
| break; |
| case SURFACE_FORMAT_NV12: |
| case SURFACE_FORMAT_YV12: |
| return 3; |
| break; |
| case SURFACE_FORMAT_A32B32G32R32F: |
| case SURFACE_FORMAT_A16B16G16R16F: |
| case SURFACE_FORMAT_A16B16G16R16: |
| case SURFACE_FORMAT_A8B8G8R8: |
| case SURFACE_FORMAT_X8B8G8R8: |
| case SURFACE_FORMAT_A8R8G8B8: |
| case SURFACE_FORMAT_X8R8G8B8: |
| return 4; |
| break; |
| default: |
| log_error("ChannelNum(): unknown surface format!\n"); |
| return 0; |
| break; |
| } |
| } |
| |
| unsigned int PlanesNum( TSurfaceFormat surfaceFormat ) |
| { |
| switch(surfaceFormat) |
| { |
| case SURFACE_FORMAT_R32F: |
| case SURFACE_FORMAT_R16F: |
| case SURFACE_FORMAT_L16: |
| case SURFACE_FORMAT_A8: |
| case SURFACE_FORMAT_L8: |
| case SURFACE_FORMAT_G32R32F: |
| case SURFACE_FORMAT_G16R16F: |
| case SURFACE_FORMAT_G16R16: |
| case SURFACE_FORMAT_A8L8: |
| case SURFACE_FORMAT_A32B32G32R32F: |
| case SURFACE_FORMAT_A16B16G16R16F: |
| case SURFACE_FORMAT_A16B16G16R16: |
| case SURFACE_FORMAT_A8B8G8R8: |
| case SURFACE_FORMAT_X8B8G8R8: |
| case SURFACE_FORMAT_A8R8G8B8: |
| case SURFACE_FORMAT_X8R8G8B8: |
| return 1; |
| break; |
| case SURFACE_FORMAT_NV12: |
| return 2; |
| break; |
| case SURFACE_FORMAT_YV12: |
| return 3; |
| break; |
| default: |
| log_error("PlanesNum(): unknown surface format!\n"); |
| return 0; |
| break; |
| } |
| } |
| |
| #if defined(_WIN32) |
| D3DFORMAT SurfaceFormatToD3D(TSurfaceFormat surfaceFormat) |
| { |
| switch(surfaceFormat) |
| { |
| case SURFACE_FORMAT_R32F: |
| return D3DFMT_R32F; |
| break; |
| case SURFACE_FORMAT_R16F: |
| return D3DFMT_R16F; |
| break; |
| case SURFACE_FORMAT_L16: |
| return D3DFMT_L16; |
| break; |
| case SURFACE_FORMAT_A8: |
| return D3DFMT_A8; |
| break; |
| case SURFACE_FORMAT_L8: |
| return D3DFMT_L8; |
| break; |
| case SURFACE_FORMAT_G32R32F: |
| return D3DFMT_G32R32F; |
| break; |
| case SURFACE_FORMAT_G16R16F: |
| return D3DFMT_G16R16F; |
| break; |
| case SURFACE_FORMAT_G16R16: |
| return D3DFMT_G16R16; |
| break; |
| case SURFACE_FORMAT_A8L8: |
| return D3DFMT_A8L8; |
| break; |
| case SURFACE_FORMAT_A32B32G32R32F: |
| return D3DFMT_A32B32G32R32F; |
| break; |
| case SURFACE_FORMAT_A16B16G16R16F: |
| return D3DFMT_A16B16G16R16F; |
| break; |
| case SURFACE_FORMAT_A16B16G16R16: |
| return D3DFMT_A16B16G16R16; |
| break; |
| case SURFACE_FORMAT_A8B8G8R8: |
| return D3DFMT_A8B8G8R8; |
| break; |
| case SURFACE_FORMAT_X8B8G8R8: |
| return D3DFMT_X8B8G8R8; |
| break; |
| case SURFACE_FORMAT_A8R8G8B8: |
| return D3DFMT_A8R8G8B8; |
| break; |
| case SURFACE_FORMAT_X8R8G8B8: |
| return D3DFMT_X8R8G8B8; |
| break; |
| case SURFACE_FORMAT_NV12: |
| return static_cast<D3DFORMAT>(MAKEFOURCC('N', 'V', '1', '2')); |
| break; |
| case SURFACE_FORMAT_YV12: |
| return static_cast<D3DFORMAT>(MAKEFOURCC('Y', 'V', '1', '2')); |
| break; |
| default: |
| log_error("SurfaceFormatToD3D(): unknown surface format!\n"); |
| return D3DFMT_R32F; |
| break; |
| } |
| } |
| #endif |
| |
| bool DeviceCreate( cl_dx9_media_adapter_type_khr adapterType, std::auto_ptr<CDeviceWrapper> &device ) |
| { |
| switch (adapterType) |
| { |
| #if defined(_WIN32) |
| case CL_ADAPTER_D3D9_KHR: |
| device = std::auto_ptr<CDeviceWrapper>(new CD3D9Wrapper()); |
| break; |
| case CL_ADAPTER_D3D9EX_KHR: |
| device = std::auto_ptr<CDeviceWrapper>(new CD3D9ExWrapper()); |
| break; |
| case CL_ADAPTER_DXVA_KHR: |
| device = std::auto_ptr<CDeviceWrapper>(new CDXVAWrapper()); |
| break; |
| #endif |
| default: |
| log_error("DeviceCreate(): Unknown adapter type!\n"); |
| return false; |
| break; |
| } |
| |
| return device->Status(); |
| } |
| |
| bool SurfaceFormatCheck( cl_dx9_media_adapter_type_khr adapterType, const CDeviceWrapper &device, TSurfaceFormat surfaceFormat ) |
| { |
| switch (adapterType) |
| { |
| #if defined(_WIN32) |
| case CL_ADAPTER_D3D9_KHR: |
| case CL_ADAPTER_D3D9EX_KHR: |
| case CL_ADAPTER_DXVA_KHR: |
| { |
| D3DFORMAT d3dFormat = SurfaceFormatToD3D(surfaceFormat); |
| LPDIRECT3D9 d3d9 = static_cast<LPDIRECT3D9>(device.D3D()); |
| D3DDISPLAYMODE d3ddm; |
| d3d9->GetAdapterDisplayMode(device.AdapterIdx(), &d3ddm); |
| |
| if( FAILED(d3d9->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, 0, D3DRTYPE_SURFACE, d3dFormat)) ) |
| return false; |
| } |
| break; |
| #endif |
| default: |
| log_error("SurfaceFormatCheck(): Unknown adapter type!\n"); |
| return false; |
| break; |
| } |
| |
| return true; |
| } |
| |
| bool SurfaceFormatToOCL(TSurfaceFormat surfaceFormat, cl_image_format &format) |
| { |
| switch(surfaceFormat) |
| { |
| case SURFACE_FORMAT_R32F: |
| format.image_channel_order = CL_R; |
| format.image_channel_data_type = CL_FLOAT; |
| break; |
| case SURFACE_FORMAT_R16F: |
| format.image_channel_order = CL_R; |
| format.image_channel_data_type = CL_HALF_FLOAT; |
| break; |
| case SURFACE_FORMAT_L16: |
| format.image_channel_order = CL_R; |
| format.image_channel_data_type = CL_UNORM_INT16; |
| break; |
| case SURFACE_FORMAT_A8: |
| format.image_channel_order = CL_A; |
| format.image_channel_data_type = CL_UNORM_INT8; |
| break; |
| case SURFACE_FORMAT_L8: |
| format.image_channel_order = CL_R; |
| format.image_channel_data_type = CL_UNORM_INT8; |
| break; |
| case SURFACE_FORMAT_G32R32F: |
| format.image_channel_order = CL_RG; |
| format.image_channel_data_type = CL_FLOAT; |
| break; |
| case SURFACE_FORMAT_G16R16F: |
| format.image_channel_order = CL_RG; |
| format.image_channel_data_type = CL_HALF_FLOAT; |
| break; |
| case SURFACE_FORMAT_G16R16: |
| format.image_channel_order = CL_RG; |
| format.image_channel_data_type = CL_UNORM_INT16; |
| break; |
| case SURFACE_FORMAT_A8L8: |
| format.image_channel_order = CL_RG; |
| format.image_channel_data_type = CL_UNORM_INT8; |
| break; |
| case SURFACE_FORMAT_A32B32G32R32F: |
| format.image_channel_order = CL_RGBA; |
| format.image_channel_data_type = CL_FLOAT; |
| break; |
| case SURFACE_FORMAT_A16B16G16R16F: |
| format.image_channel_order = CL_RGBA; |
| format.image_channel_data_type = CL_HALF_FLOAT; |
| break; |
| case SURFACE_FORMAT_A16B16G16R16: |
| format.image_channel_order = CL_RGBA; |
| format.image_channel_data_type = CL_UNORM_INT16; |
| break; |
| case SURFACE_FORMAT_A8B8G8R8: |
| format.image_channel_order = CL_RGBA; |
| format.image_channel_data_type = CL_UNORM_INT8; |
| break; |
| case SURFACE_FORMAT_X8B8G8R8: |
| format.image_channel_order = CL_RGBA; |
| format.image_channel_data_type = CL_UNORM_INT8; |
| break; |
| case SURFACE_FORMAT_A8R8G8B8: |
| format.image_channel_order = CL_BGRA; |
| format.image_channel_data_type = CL_UNORM_INT8; |
| break; |
| case SURFACE_FORMAT_X8R8G8B8: |
| format.image_channel_order = CL_BGRA; |
| format.image_channel_data_type = CL_UNORM_INT8; |
| break; |
| case SURFACE_FORMAT_NV12: |
| format.image_channel_order = CL_R; |
| format.image_channel_data_type = CL_UNORM_INT8; |
| break; |
| case SURFACE_FORMAT_YV12: |
| format.image_channel_order = CL_R; |
| format.image_channel_data_type = CL_UNORM_INT8; |
| break; |
| default: |
| log_error("SurfaceFormatToOCL(): Unknown surface format!\n"); |
| return false; |
| break; |
| } |
| |
| return true; |
| } |
| |
| void SurfaceFormatToString( TSurfaceFormat surfaceFormat, std::string &str ) |
| { |
| switch(surfaceFormat) |
| { |
| case SURFACE_FORMAT_R32F: |
| str = "R32F"; |
| break; |
| case SURFACE_FORMAT_R16F: |
| str = "R16F"; |
| break; |
| case SURFACE_FORMAT_L16: |
| str = "L16"; |
| break; |
| case SURFACE_FORMAT_A8: |
| str = "A8"; |
| break; |
| case SURFACE_FORMAT_L8: |
| str = "L8"; |
| break; |
| case SURFACE_FORMAT_G32R32F: |
| str = "G32R32F"; |
| break; |
| case SURFACE_FORMAT_G16R16F: |
| str = "G16R16F"; |
| break; |
| case SURFACE_FORMAT_G16R16: |
| str = "G16R16"; |
| break; |
| case SURFACE_FORMAT_A8L8: |
| str = "A8L8"; |
| break; |
| case SURFACE_FORMAT_A32B32G32R32F: |
| str = "A32B32G32R32F"; |
| break; |
| case SURFACE_FORMAT_A16B16G16R16F: |
| str = "A16B16G16R16F"; |
| break; |
| case SURFACE_FORMAT_A16B16G16R16: |
| str = "A16B16G16R16"; |
| break; |
| case SURFACE_FORMAT_A8B8G8R8: |
| str = "A8B8G8R8"; |
| break; |
| case SURFACE_FORMAT_X8B8G8R8: |
| str = "X8B8G8R8"; |
| break; |
| case SURFACE_FORMAT_A8R8G8B8: |
| str = "A8R8G8B8"; |
| break; |
| case SURFACE_FORMAT_X8R8G8B8: |
| str = "X8R8G8B8"; |
| break; |
| case SURFACE_FORMAT_NV12: |
| str = "NV12"; |
| break; |
| case SURFACE_FORMAT_YV12: |
| str = "YV12"; |
| break; |
| default: |
| log_error("SurfaceFormatToString(): unknown surface format!\n"); |
| str = "unknown"; |
| break; |
| } |
| } |
| |
| bool MediaSurfaceCreate(cl_dx9_media_adapter_type_khr adapterType, unsigned int width, unsigned int height, TSurfaceFormat surfaceFormat, |
| CDeviceWrapper &device, std::auto_ptr<CSurfaceWrapper> &surface, bool sharedHandle, void **objectSharedHandle) |
| { |
| switch (adapterType) |
| { |
| #if defined(_WIN32) |
| case CL_ADAPTER_D3D9_KHR: |
| { |
| surface = std::auto_ptr<CD3D9SurfaceWrapper>(new CD3D9SurfaceWrapper); |
| CD3D9SurfaceWrapper *d3dSurface = static_cast<CD3D9SurfaceWrapper *>(surface.get()); |
| HRESULT hr = 0; |
| D3DFORMAT d3dFormat = SurfaceFormatToD3D(surfaceFormat); |
| LPDIRECT3DDEVICE9 d3d9Device = (LPDIRECT3DDEVICE9)device.Device(); |
| hr = d3d9Device->CreateOffscreenPlainSurface(width, height, d3dFormat, D3DPOOL_DEFAULT, &(*d3dSurface), |
| sharedHandle ? objectSharedHandle: 0); |
| |
| if ( FAILED(hr)) |
| { |
| log_error("CreateOffscreenPlainSurface failed\n"); |
| return false; |
| } |
| } |
| break; |
| case CL_ADAPTER_D3D9EX_KHR: |
| { |
| surface = std::auto_ptr<CD3D9SurfaceWrapper>(new CD3D9SurfaceWrapper); |
| CD3D9SurfaceWrapper *d3dSurface = static_cast<CD3D9SurfaceWrapper *>(surface.get()); |
| HRESULT hr = 0; |
| D3DFORMAT d3dFormat = SurfaceFormatToD3D(surfaceFormat); |
| LPDIRECT3DDEVICE9EX d3d9ExDevice = (LPDIRECT3DDEVICE9EX)device.Device(); |
| hr = d3d9ExDevice->CreateOffscreenPlainSurface(width, height, d3dFormat, D3DPOOL_DEFAULT, &(*d3dSurface), |
| sharedHandle ? objectSharedHandle: 0); |
| |
| if ( FAILED(hr)) |
| { |
| log_error("CreateOffscreenPlainSurface failed\n"); |
| return false; |
| } |
| } |
| break; |
| case CL_ADAPTER_DXVA_KHR: |
| { |
| surface = std::auto_ptr<CD3D9SurfaceWrapper>(new CD3D9SurfaceWrapper); |
| CD3D9SurfaceWrapper *d3dSurface = static_cast<CD3D9SurfaceWrapper *>(surface.get()); |
| HRESULT hr = 0; |
| D3DFORMAT d3dFormat = SurfaceFormatToD3D(surfaceFormat); |
| IDXVAHD_Device *dxvaDevice = (IDXVAHD_Device *)device.Device(); |
| hr = dxvaDevice->CreateVideoSurface(width, height, d3dFormat, D3DPOOL_DEFAULT, 0, |
| DXVAHD_SURFACE_TYPE_VIDEO_INPUT, 1, &(*d3dSurface), sharedHandle ? objectSharedHandle: 0); |
| |
| if ( FAILED(hr)) |
| { |
| log_error("CreateVideoSurface failed\n"); |
| return false; |
| } |
| } |
| break; |
| #endif |
| default: |
| log_error("MediaSurfaceCreate(): Unknown adapter type!\n"); |
| return false; |
| break; |
| } |
| |
| return true; |
| } |
| |
| cl_int deviceExistForCLTest(cl_platform_id platform, |
| cl_dx9_media_adapter_type_khr media_adapters_type, |
| void *media_adapters, |
| CResult &result, |
| TSharedHandleType sharedHandle /*default SHARED_HANDLE_ENABLED*/ |
| ) |
| { |
| cl_int _error; |
| cl_uint devicesAllNum = 0; |
| std::string sharedHandleStr = (sharedHandle == SHARED_HANDLE_ENABLED)? "yes": "no"; |
| std::string adapterStr; |
| AdapterToString(media_adapters_type, adapterStr); |
| |
| _error = clGetDeviceIDsFromDX9MediaAdapterKHR(platform, 1, |
| &media_adapters_type, &media_adapters, CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 0, 0, &devicesAllNum); |
| |
| if (_error != CL_SUCCESS) |
| { |
| if(_error != CL_DEVICE_NOT_FOUND) |
| { |
| log_error("clGetDeviceIDsFromDX9MediaAdapterKHR failed: %s\n", IGetErrorString(_error)); |
| result.ResultSub(CResult::TEST_ERROR); |
| } |
| else |
| { |
| log_info("Skipping test case, device type is not supported by a device (adapter type: %s, shared handle: %s)\n", adapterStr.c_str(), sharedHandleStr.c_str()); |
| result.ResultSub(CResult::TEST_NOTSUPPORTED); |
| } |
| } |
| |
| return _error; |
| } |