/* * Copyright (c) Advanced Micro Devices, Inc., or its affiliates. * * SPDX-License-Identifier: MIT */ /** * @addtogroup surfCubemap surfCubemap * @{ * @ingroup SurfaceTest */ #include #include #include #include "surf_common.h" #pragma clang diagnostic ignored "-Wunused-variable" #pragma clang diagnostic ignored "-Wunused-parameter" #define LOG_DATA 0 template __global__ void surfCubemapKernelR(hipSurfaceObject_t surfaceObject, T* outputData, int width, int height) { #if !__HIP_NO_IMAGE_SUPPORT int x = blockIdx.x * blockDim.x + threadIdx.x; int y = blockIdx.y * blockDim.y + threadIdx.y; if (x < width && y < height) { surfCubemapread(outputData + y * width + x, surfaceObject, x * sizeof(T), y, 0); } #endif } template __global__ void surfCubemapKernelW(hipSurfaceObject_t surfaceObject, T* inputData, int width, int height) { #if !__HIP_NO_IMAGE_SUPPORT int x = blockIdx.x * blockDim.x + threadIdx.x; int y = blockIdx.y * blockDim.y + threadIdx.y; if (x < width && y < height) { surfCubemapwrite(inputData[y * width + x], surfaceObject, x * sizeof(T), y, 0); } #endif } template __global__ void surfCubemapKernelRW(hipSurfaceObject_t surfaceObject, hipSurfaceObject_t outputSurfObj, int width, int height) { #if !__HIP_NO_IMAGE_SUPPORT int x = blockIdx.x * blockDim.x + threadIdx.x; int y = blockIdx.y * blockDim.y + threadIdx.y; if (x < width && y < height) { T data; surfCubemapread(&data, surfaceObject, x * sizeof(T), y, 0); surfCubemapwrite(data, outputSurfObj, x * sizeof(T), y, 0); } #endif } template static void runTestR(const int width, const int height) { unsigned int size = width * height * sizeof(T); T* hData = (T*)malloc(size); memset(hData, 0, size); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { initVal(hData[i * width + j]); } } hipChannelFormatDesc channelDesc = hipCreateChannelDesc(); hipArray_t hipArray = nullptr; HIP_CHECK(hipMallocArray(&hipArray, &channelDesc, width, height, hipArraySurfaceLoadStore)); // Need set source pitch, but we don't have any padding here const size_t spitch = width * sizeof(T); HIP_CHECK( hipMemcpy2DToArray(hipArray, 0, 0, hData, spitch, spitch, height, hipMemcpyHostToDevice)); hipResourceDesc resDesc; memset(&resDesc, 0, sizeof(resDesc)); resDesc.resType = hipResourceTypeArray; resDesc.res.array.array = hipArray; // Create surface object hipSurfaceObject_t surfaceObject = 0; HIP_CHECK(hipCreateSurfaceObject(&surfaceObject, &resDesc)); T* hOutputData = nullptr; HIP_CHECK(hipHostMalloc((void**)&hOutputData, size)); memset(hOutputData, 0, size); dim3 dimBlock(16, 16, 1); dim3 dimGrid((width + dimBlock.x - 1) / dimBlock.x, (height + dimBlock.y - 1) / dimBlock.y, 1); surfCubemapKernelR<<>>(surfaceObject, hOutputData, width, height); HIP_CHECK(hipGetLastError()); HIP_CHECK(hipDeviceSynchronize()); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { int index = i * width + j; if (!isEqual(hData[index], hOutputData[index])) { printf("Difference [ %d %d ]:%s ----%s\n", i, j, getString(hData[index]).c_str(), getString(hOutputData[index]).c_str()); REQUIRE(false); } } } HIP_CHECK(hipDestroySurfaceObject(surfaceObject)); HIP_CHECK(hipFreeArray(hipArray)); free(hData); HIP_CHECK(hipHostFree(hOutputData)); } template static void runTestW(const int width, const int height) { unsigned int size = width * height * sizeof(T); T* hData = nullptr; HIP_CHECK(hipHostMalloc((void**)&hData, size)); memset(hData, 0, size); hipChannelFormatDesc channelDesc = hipCreateChannelDesc(); hipArray_t hipArray = nullptr; HIP_CHECK(hipMallocArray(&hipArray, &channelDesc, width, height, hipArraySurfaceLoadStore)); // Need set source pitch, but we don't have any padding here const size_t spitch = width * sizeof(T); HIP_CHECK( hipMemcpy2DToArray(hipArray, 0, 0, hData, spitch, spitch, height, hipMemcpyHostToDevice)); hipResourceDesc resDesc; memset(&resDesc, 0, sizeof(resDesc)); resDesc.resType = hipResourceTypeArray; resDesc.res.array.array = hipArray; // Create surface object hipSurfaceObject_t surfaceObject = 0; HIP_CHECK(hipCreateSurfaceObject(&surfaceObject, &resDesc)); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { initVal(hData[i * width + j]); } } dim3 dimBlock(16, 16, 1); dim3 dimGrid((width + dimBlock.x - 1) / dimBlock.x, (height + dimBlock.y - 1) / dimBlock.y, 1); surfCubemapKernelW<<>>(surfaceObject, hData, width, height); HIP_CHECK(hipGetLastError()); HIP_CHECK(hipDeviceSynchronize()); T* hOutputData = (T*)malloc(size); memset(hOutputData, 0, size); HIP_CHECK(hipMemcpy2DFromArray(hOutputData, spitch, hipArray, 0, 0, spitch, height, hipMemcpyDeviceToHost)); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { int index = i * width + j; if (!isEqual(hData[index], hOutputData[index])) { printf("Difference [ %d %d ]:%s ----%s\n", i, j, getString(hData[index]).c_str(), getString(hOutputData[index]).c_str()); REQUIRE(false); } } } HIP_CHECK(hipDestroySurfaceObject(surfaceObject)); HIP_CHECK(hipFreeArray(hipArray)); HIP_CHECK(hipHostFree(hData)); free(hOutputData); } template static void runTestRW(const int width, const int height) { unsigned int size = width * height * sizeof(T); T* hData = (T*)malloc(size); memset(hData, 0, size); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { initVal(hData[i * width + j]); } } #if LOG_DATA printf("hData: "); for (int i = 0; i < 32; i++) { printf("%s ", getString(hData[i]).c_str()); } printf("\n"); #endif hipChannelFormatDesc channelDesc = hipCreateChannelDesc(); hipArray_t hipArray = nullptr, hipOutArray = nullptr; HIP_CHECK(hipMallocArray(&hipArray, &channelDesc, width, height, hipArraySurfaceLoadStore)); // Need set source pitch, but we don't have any padding here const size_t spitch = width * sizeof(T); HIP_CHECK( hipMemcpy2DToArray(hipArray, 0, 0, hData, spitch, spitch, height, hipMemcpyHostToDevice)); hipResourceDesc resDesc; memset(&resDesc, 0, sizeof(resDesc)); resDesc.resType = hipResourceTypeArray; resDesc.res.array.array = hipArray; // Create surface object hipSurfaceObject_t surfaceObject = 0; HIP_CHECK(hipCreateSurfaceObject(&surfaceObject, &resDesc)); HIP_CHECK(hipMallocArray(&hipOutArray, &channelDesc, width, height, hipArraySurfaceLoadStore)); hipResourceDesc resOutDesc; memset(&resOutDesc, 0, sizeof(resOutDesc)); resOutDesc.resType = hipResourceTypeArray; resOutDesc.res.array.array = hipOutArray; hipSurfaceObject_t outSurfaceObject = 0; HIP_CHECK(hipCreateSurfaceObject(&outSurfaceObject, &resOutDesc)); dim3 dimBlock(16, 16, 1); dim3 dimGrid((width + dimBlock.x - 1) / dimBlock.x, (height + dimBlock.y - 1) / dimBlock.y, 1); surfCubemapKernelRW<<>>(surfaceObject, outSurfaceObject, width, height); HIP_CHECK(hipGetLastError()); HIP_CHECK(hipDeviceSynchronize()); T* hOutputData = (T*)malloc(size); memset(hOutputData, 0, size); HIP_CHECK(hipMemcpy2DFromArray(hOutputData, spitch, hipOutArray, 0, 0, spitch, height, hipMemcpyDeviceToHost)); #if LOG_DATA printf("dData: "); for (int i = 0; i < 32; i++) { printf("%s ", getString(hOutputData[i]).c_str()); } printf("\n"); #endif for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { int index = i * width + j; if (!isEqual(hData[index], hOutputData[index])) { printf("Difference [ %d %d ]:%s ----%s\n", i, j, getString(hData[index]).c_str(), getString(hOutputData[index]).c_str()); REQUIRE(false); } } } HIP_CHECK(hipDestroySurfaceObject(surfaceObject)); HIP_CHECK(hipDestroySurfaceObject(outSurfaceObject)); HIP_CHECK(hipFreeArray(hipArray)); HIP_CHECK(hipFreeArray(hipOutArray)); free(hData); free(hOutputData); } /** * Test Description * ------------------------ * - Basic test for `surfCubemapread` with different types and dimensions. * Test source * ------------------------ * - unit/surface/surfCubemap.cc * Test requirements * ------------------------ * - HIP_VERSION >= 5.7 */ HIP_TEMPLATE_TEST_CASE(Unit_surfCubemapread_Positive_Basic, char, unsigned char, short, unsigned short, int, unsigned int, float) { CHECK_IMAGE_SUPPORT; const int width = GENERATE(31, 67); const int height = GENERATE(131, 263); runTestR>(width, height); runTestR>(width, height); runTestR>(width, height); runTestR>(width, height); } /** * Test Description * ------------------------ * - Basic test for `surfCubemapwrite` with different types and dimensions. * Test source * ------------------------ * - unit/surface/surfCubemap.cc * Test requirements * ------------------------ * - HIP_VERSION >= 5.7 */ HIP_TEMPLATE_TEST_CASE(Unit_surfCubemapwrite_Positive_Basic, char, unsigned char, short, unsigned short, int, unsigned int, float) { CHECK_IMAGE_SUPPORT; const int width = GENERATE(31, 67); const int height = GENERATE(131, 263); runTestW>(width, height); runTestW>(width, height); runTestW>(width, height); runTestW>(width, height); } /** * Test Description * ------------------------ * - Basic test for `surfCubemapread` and `surfCubemapwrite` together, with different types and * dimensions. Test source * ------------------------ * - unit/surface/surfCubemap.cc * Test requirements * ------------------------ * - HIP_VERSION >= 5.7 */ HIP_TEMPLATE_TEST_CASE(Unit_surfCubemap_Positive_ReadWrite, char, unsigned char, short, unsigned short, int, unsigned int, float) { CHECK_IMAGE_SUPPORT; const int width = GENERATE(31, 67); const int height = GENERATE(131, 263); runTestRW>(width, height); runTestRW>(width, height); runTestRW>(width, height); runTestRW>(width, height); } /** * End doxygen group SurfaceTest. * @} */