mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
Merge branch 'main' into cl_khr_unified_svm
This commit is contained in:
110
.github/workflows/presubmit.yml
vendored
110
.github/workflows/presubmit.yml
vendored
@@ -5,34 +5,26 @@ jobs:
|
||||
build:
|
||||
name: Build ${{ matrix.os }} ${{ matrix.arch }}${{ matrix.extra }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
JOB_ARCHITECTURE: ${{ matrix.arch }}
|
||||
JOB_ENABLE_GL: ${{ matrix.gl }}
|
||||
JOB_ENABLE_DEBUG: ${{ matrix.debug }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
mainmatrix: [true]
|
||||
build-type: [Release]
|
||||
gl: [0]
|
||||
os: [ubuntu-22.04, macos-latest, windows-latest]
|
||||
include:
|
||||
- os: ubuntu-22.04
|
||||
mainmatrix: true
|
||||
gl: 1
|
||||
extra: " gl"
|
||||
- os: ubuntu-22.04
|
||||
mainmatrix: false
|
||||
arch: arm
|
||||
- os: ubuntu-22.04
|
||||
mainmatrix: false
|
||||
arch: aarch64
|
||||
debug: 1
|
||||
build-type: Debug
|
||||
extra: " debug"
|
||||
- os: ubuntu-22.04
|
||||
mainmatrix: false
|
||||
arch: android-arm
|
||||
android_arch_abi: armeabi-v7a
|
||||
- os: ubuntu-22.04
|
||||
mainmatrix: false
|
||||
arch: android-aarch64
|
||||
android_arch_abi: arm64-v8a
|
||||
steps:
|
||||
@@ -84,9 +76,101 @@ jobs:
|
||||
echo "ANDROID_NDK=$ANDROID_NDK" >> $GITHUB_ENV
|
||||
export ANDROID_ARCH_ABI=${{ matrix.android_arch_abi }}
|
||||
echo "ANDROID_ARCH_ABI=$ANDROID_ARCH_ABI" >> $GITHUB_ENV
|
||||
- name: Build
|
||||
- name: Prepare CMake Toolchain file
|
||||
shell: bash
|
||||
run: ./presubmit.sh
|
||||
run: |
|
||||
if [[ '${{ matrix.arch }}' == android-* ]]; then
|
||||
TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake
|
||||
else
|
||||
TOOLCHAIN_FILE='${{ github.workspace }}'/toolchain.cmake
|
||||
touch ${TOOLCHAIN_FILE}
|
||||
fi
|
||||
|
||||
TOOLCHAIN_PREFIX_arm=arm-linux-gnueabihf
|
||||
TOOLCHAIN_PREFIX_aarch64=aarch64-linux-gnu
|
||||
|
||||
if [[ '${{ matrix.arch }}' != android-* ]]; then
|
||||
if [[ '${{ matrix.arch }}' != "" && ${RUNNER_OS} != "Windows" ]]; then
|
||||
TOOLCHAIN_PREFIX_VAR=TOOLCHAIN_PREFIX_${{ matrix.arch }}
|
||||
TOOLCHAIN_PREFIX=${!TOOLCHAIN_PREFIX_VAR}
|
||||
|
||||
echo "SET(CMAKE_SYSTEM_NAME Linux)" >> ${TOOLCHAIN_FILE}
|
||||
echo "SET(CMAKE_SYSTEM_PROCESSOR ${{ matrix.arch }})" >> ${TOOLCHAIN_FILE}
|
||||
echo "SET(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)" >> ${TOOLCHAIN_FILE}
|
||||
echo "SET(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)" >> ${TOOLCHAIN_FILE}
|
||||
echo "SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)" >> ${TOOLCHAIN_FILE}
|
||||
echo "SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)" >> ${TOOLCHAIN_FILE}
|
||||
echo "SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)" >> ${TOOLCHAIN_FILE}
|
||||
fi
|
||||
fi
|
||||
echo "TOOLCHAIN_FILE=${TOOLCHAIN_FILE}" >> $GITHUB_ENV
|
||||
- name: Prepare Android CMake arguments
|
||||
if: ${{ matrix.arch == 'android-arm' || matrix.arch == 'android-aarch64' }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo "CMAKE_CONFIG_ARGS_ANDROID=-DCMAKE_ANDROID_ARCH_ABI=${ANDROID_ARCH_ABI}" >> $GITHUB_ENV
|
||||
- name: Fetch and build OpenCL ICD Loader
|
||||
shell: bash
|
||||
run: |
|
||||
git clone https://github.com/KhronosGroup/OpenCL-ICD-Loader.git
|
||||
cd OpenCL-ICD-Loader
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} \
|
||||
-DOPENCL_ICD_LOADER_HEADERS_DIR='${{ github.workspace }}'/OpenCL-Headers/ \
|
||||
"${CMAKE_CONFIG_ARGS_ANDROID}"
|
||||
cmake --build . --parallel
|
||||
- name: Fetch Vulkan Headers
|
||||
shell: bash
|
||||
run: |
|
||||
git clone https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||
- name: Fetch and build Vulkan Loader
|
||||
if: ${{ matrix.arch != 'android-arm' && matrix.arch != 'android-aarch64' }}
|
||||
shell: bash
|
||||
run: |
|
||||
git clone https://github.com/KhronosGroup/Vulkan-Loader.git
|
||||
cd Vulkan-Loader
|
||||
mkdir build
|
||||
cd build
|
||||
python3 ../scripts/update_deps.py
|
||||
cmake .. -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} \
|
||||
-DBUILD_WSI_XLIB_SUPPORT=OFF \
|
||||
-DBUILD_WSI_XCB_SUPPORT=OFF \
|
||||
-DBUILD_WSI_WAYLAND_SUPPORT=OFF \
|
||||
-C helper.cmake ..
|
||||
cmake --build . --parallel
|
||||
- name: Configure and build
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
if [[ ${RUNNER_OS} == "Windows" ]]; then
|
||||
CMAKE_OPENCL_LIBRARIES_OPTION="OpenCL"
|
||||
else
|
||||
CMAKE_OPENCL_LIBRARIES_OPTION="-lOpenCL"
|
||||
if [[ '${{ matrix.arch }}' != android-* ]]; then
|
||||
CMAKE_OPENCL_LIBRARIES_OPTION="${CMAKE_OPENCL_LIBRARIES_OPTION} -lpthread"
|
||||
fi
|
||||
fi
|
||||
cmake .. -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \
|
||||
-DCMAKE_CACHE_OPTIONS="-DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache" \
|
||||
-DCL_INCLUDE_DIR='${{ github.workspace }}'/OpenCL-Headers \
|
||||
-DCL_LIB_DIR='${{ github.workspace }}'/OpenCL-ICD-Loader/build \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} \
|
||||
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=./bin \
|
||||
-DOPENCL_LIBRARIES="${CMAKE_OPENCL_LIBRARIES_OPTION}" \
|
||||
-DUSE_CL_EXPERIMENTAL=ON \
|
||||
-DGL_IS_SUPPORTED=${{ matrix.gl }} \
|
||||
-DVULKAN_IS_SUPPORTED=ON \
|
||||
-DVULKAN_INCLUDE_DIR='${{ github.workspace }}'/Vulkan-Headers/include/ \
|
||||
-DVULKAN_LIB_DIR='${{ github.workspace }}'/Vulkan-Loader/build/loader/ \
|
||||
"${CMAKE_CONFIG_ARGS_ANDROID}"
|
||||
cmake --build . --parallel
|
||||
formatcheck:
|
||||
name: Check code format
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
@@ -7,7 +7,7 @@ project(CLConform${CONFORMANCE_SUFFIX})
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
add_definitions(-DCL_TARGET_OPENCL_VERSION=300)
|
||||
@@ -100,7 +100,11 @@ if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?Clang"
|
||||
add_cxx_flag_if_supported(-Wmisleading-indentation)
|
||||
add_cxx_flag_if_supported(-Wunused-function)
|
||||
add_cxx_flag_if_supported(-Wunused-variable)
|
||||
add_cxx_flag_if_supported(-Werror)
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.24")
|
||||
set(CMAKE_COMPILE_WARNING_AS_ERROR ON)
|
||||
else()
|
||||
add_cxx_flag_if_supported(-Werror)
|
||||
endif()
|
||||
if(NOT CMAKE_BUILD_TYPE MATCHES "Release|RelWithDebInfo|MinSizeRel")
|
||||
# Enable more warnings if not doing a release build.
|
||||
add_cxx_flag_if_supported(-Wall)
|
||||
|
||||
13
README.md
13
README.md
@@ -14,6 +14,9 @@ Compiling the CTS requires the following CMake configuration options to be set:
|
||||
* `CL_INCLUDE_DIR` Points to the unified
|
||||
[OpenCL-Headers](https://github.com/KhronosGroup/OpenCL-Headers).
|
||||
* `CL_LIB_DIR` Directory containing the OpenCL library to build against.
|
||||
* `SPIRV_TOOLS_DIR` Directory containing the `spirv-as` and `spirv-val` binaries
|
||||
to be used in the CTS build process. Alternatively, the location to these binaries
|
||||
can be provided via the `PATH` variable.
|
||||
* `OPENCL_LIBRARIES` Name of the OpenCL library to link.
|
||||
|
||||
It is advised that the [OpenCL ICD-Loader](https://github.com/KhronosGroup/OpenCL-ICD-Loader)
|
||||
@@ -29,16 +32,26 @@ a build, and compile.
|
||||
git clone https://github.com/KhronosGroup/OpenCL-CTS.git
|
||||
git clone https://github.com/KhronosGroup/OpenCL-Headers.git
|
||||
git clone https://github.com/KhronosGroup/OpenCL-ICD-Loader.git
|
||||
git clone https://github.com/KhronosGroup/SPIRV-Tools.git
|
||||
git clone https://github.com/KhronosGroup/SPIRV-Headers.git SPIRV-Tools/external/spirv-headers
|
||||
git clone https://github.com/google/effcee.git SPIRV-Tools/external/effcee
|
||||
git clone https://github.com/google/re2.git SPIRV-Tools/external/re2
|
||||
|
||||
|
||||
mkdir OpenCL-ICD-Loader/build
|
||||
cmake -S OpenCL-ICD-Loader -B OpenCL-ICD-Loader/build \
|
||||
-DOPENCL_ICD_LOADER_HEADERS_DIR=$PWD/OpenCL-Headers
|
||||
cmake --build ./OpenCL-ICD-Loader/build --config Release
|
||||
|
||||
mkdir SPIRV-Tools/build
|
||||
cmake -S SPIRV-Tools -B SPIRV-Tools/build -DSPIRV_SKIP_TESTS=ON
|
||||
cmake --build SPIRV-Tools/build --config Release
|
||||
|
||||
mkdir OpenCL-CTS/build
|
||||
cmake -S OpenCL-CTS -B OpenCL-CTS/build \
|
||||
-DCL_INCLUDE_DIR=$PWD/OpenCL-Headers \
|
||||
-DCL_LIB_DIR=$PWD/OpenCL-ICD-Loader/build \
|
||||
-DSPIRV_TOOLS_DIR=$PWD/SPIRV-Tools/build/tools/ \
|
||||
-DOPENCL_LIBRARIES=OpenCL
|
||||
cmake --build OpenCL-CTS/build --config Release
|
||||
```
|
||||
|
||||
112
presubmit.sh
112
presubmit.sh
@@ -1,112 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
export TOP=$(pwd)
|
||||
|
||||
TOOLCHAIN_PREFIX_arm=arm-linux-gnueabihf
|
||||
TOOLCHAIN_PREFIX_aarch64=aarch64-linux-gnu
|
||||
|
||||
if [[ ${JOB_ARCHITECTURE} == android-* ]]; then
|
||||
TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake
|
||||
CMAKE_CONFIG_ARGS_ANDROID="-DCMAKE_ANDROID_ARCH_ABI=${ANDROID_ARCH_ABI}"
|
||||
else
|
||||
TOOLCHAIN_FILE=${TOP}/toolchain.cmake
|
||||
touch ${TOOLCHAIN_FILE}
|
||||
fi
|
||||
|
||||
BUILD_OPENGL_TEST="OFF"
|
||||
BUILD_VULKAN_TEST="ON"
|
||||
|
||||
cmake --version
|
||||
echo
|
||||
|
||||
# Prepare toolchain if needed
|
||||
if [[ ${JOB_ARCHITECTURE} != android-* ]]; then
|
||||
if [[ ${JOB_ARCHITECTURE} != "" && ${RUNNER_OS} != "Windows" ]]; then
|
||||
TOOLCHAIN_PREFIX_VAR=TOOLCHAIN_PREFIX_${JOB_ARCHITECTURE}
|
||||
TOOLCHAIN_PREFIX=${!TOOLCHAIN_PREFIX_VAR}
|
||||
|
||||
echo "SET(CMAKE_SYSTEM_NAME Linux)" >> ${TOOLCHAIN_FILE}
|
||||
echo "SET(CMAKE_SYSTEM_PROCESSOR ${JOB_ARCHITECTURE})" >> ${TOOLCHAIN_FILE}
|
||||
echo "SET(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)" >> ${TOOLCHAIN_FILE}
|
||||
echo "SET(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)" >> ${TOOLCHAIN_FILE}
|
||||
echo "SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)" >> ${TOOLCHAIN_FILE}
|
||||
echo "SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)" >> ${TOOLCHAIN_FILE}
|
||||
echo "SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)" >> ${TOOLCHAIN_FILE}
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ( ${JOB_ARCHITECTURE} == "" && ${JOB_ENABLE_GL} == "1" ) ]]; then
|
||||
BUILD_OPENGL_TEST="ON"
|
||||
fi
|
||||
|
||||
if [[ ${JOB_ENABLE_DEBUG} == 1 ]]; then
|
||||
BUILD_CONFIG="Debug"
|
||||
else
|
||||
BUILD_CONFIG="Release"
|
||||
fi
|
||||
|
||||
#Vulkan Headers
|
||||
git clone https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||
|
||||
# Get and build loader
|
||||
git clone https://github.com/KhronosGroup/OpenCL-ICD-Loader.git
|
||||
cd ${TOP}/OpenCL-ICD-Loader
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} \
|
||||
-DOPENCL_ICD_LOADER_HEADERS_DIR=${TOP}/OpenCL-Headers/ \
|
||||
"${CMAKE_CONFIG_ARGS_ANDROID}"
|
||||
cmake --build . --parallel
|
||||
|
||||
#Vulkan Loader
|
||||
if [[ ${JOB_ARCHITECTURE} != android-* ]]; then
|
||||
# Building the Vulkan loader is not supported on Android,
|
||||
# instead, the loader is shipped as part of the operating system
|
||||
cd ${TOP}
|
||||
git clone https://github.com/KhronosGroup/Vulkan-Loader.git
|
||||
cd Vulkan-Loader
|
||||
mkdir build
|
||||
cd build
|
||||
python3 ../scripts/update_deps.py
|
||||
cmake .. -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} \
|
||||
-DBUILD_WSI_XLIB_SUPPORT=OFF \
|
||||
-DBUILD_WSI_XCB_SUPPORT=OFF \
|
||||
-DBUILD_WSI_WAYLAND_SUPPORT=OFF \
|
||||
-C helper.cmake ..
|
||||
cmake --build . --parallel
|
||||
fi
|
||||
|
||||
# Build CTS
|
||||
cd ${TOP}
|
||||
ls -l
|
||||
mkdir build
|
||||
cd build
|
||||
if [[ ${RUNNER_OS} == "Windows" ]]; then
|
||||
CMAKE_OPENCL_LIBRARIES_OPTION="OpenCL"
|
||||
else
|
||||
CMAKE_OPENCL_LIBRARIES_OPTION="-lOpenCL"
|
||||
if [[ ${JOB_ARCHITECTURE} != android-* ]]; then
|
||||
CMAKE_OPENCL_LIBRARIES_OPTION="${CMAKE_OPENCL_LIBRARIES_OPTION} -lpthread"
|
||||
fi
|
||||
fi
|
||||
cmake .. -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE="${BUILD_CONFIG}" \
|
||||
-DCMAKE_CACHE_OPTIONS="-DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache" \
|
||||
-DCL_INCLUDE_DIR=${TOP}/OpenCL-Headers \
|
||||
-DCL_LIB_DIR=${TOP}/OpenCL-ICD-Loader/build \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} \
|
||||
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=./bin \
|
||||
-DOPENCL_LIBRARIES="${CMAKE_OPENCL_LIBRARIES_OPTION}" \
|
||||
-DUSE_CL_EXPERIMENTAL=ON \
|
||||
-DGL_IS_SUPPORTED=${BUILD_OPENGL_TEST} \
|
||||
-DVULKAN_IS_SUPPORTED=${BUILD_VULKAN_TEST} \
|
||||
-DVULKAN_INCLUDE_DIR=${TOP}/Vulkan-Headers/include/ \
|
||||
-DVULKAN_LIB_DIR=${TOP}/Vulkan-Loader/build/loader/ \
|
||||
"${CMAKE_CONFIG_ARGS_ANDROID}"
|
||||
cmake --build . --parallel
|
||||
@@ -13,12 +13,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _setup_h
|
||||
#define _setup_h
|
||||
#ifndef _gl_setup_h
|
||||
#define _gl_setup_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include "gl_headers.h"
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/opencl.h>
|
||||
@@ -36,13 +37,11 @@ class GLEnvironment
|
||||
GLEnvironment() {}
|
||||
virtual ~GLEnvironment() {}
|
||||
|
||||
virtual int Init( int *argc, char **argv, int use_opengl_32 ) = 0;
|
||||
virtual int Init(int *argc, char **argv, int use_opengl_32) = 0;
|
||||
virtual cl_context CreateCLContext( void ) = 0;
|
||||
virtual int SupportsCLGLInterop( cl_device_type device_type) = 0;
|
||||
|
||||
static GLEnvironment * Instance( void );
|
||||
|
||||
|
||||
static GLEnvironment *Instance(void);
|
||||
};
|
||||
|
||||
#endif // _setup_h
|
||||
#endif // _gl_setup_h
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Copyright (c) 2024 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
|
||||
@@ -25,65 +25,74 @@ private:
|
||||
public:
|
||||
OSXGLEnvironment()
|
||||
{
|
||||
mCGLContext = NULL;
|
||||
mIsGlutInit = false;
|
||||
mCGLContext = NULL;
|
||||
mShareGroup = NULL;
|
||||
mPlatform = NULL;
|
||||
}
|
||||
|
||||
virtual int Init( int *argc, char **argv, int use_opengl_32 )
|
||||
int Init(int *argc, char **argv, int use_opengl_32) override
|
||||
{
|
||||
if (!use_opengl_32)
|
||||
{
|
||||
if (!use_opengl_32) {
|
||||
if (!mIsGlutInit)
|
||||
{
|
||||
// Create a GLUT window to render into
|
||||
glutInit(argc, argv);
|
||||
glutInitWindowSize(512, 512);
|
||||
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
|
||||
glutCreateWindow("OpenCL <-> OpenGL Test");
|
||||
mIsGlutInit = true;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
CGLPixelFormatAttribute attribs[] = {
|
||||
kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core,
|
||||
kCGLPFAAllowOfflineRenderers,
|
||||
kCGLPFANoRecovery,
|
||||
kCGLPFAAccelerated,
|
||||
kCGLPFADoubleBuffer,
|
||||
(CGLPixelFormatAttribute)0
|
||||
};
|
||||
|
||||
CGLError err;
|
||||
CGLPixelFormatObj pix;
|
||||
GLint npix;
|
||||
err = CGLChoosePixelFormat (attribs, &pix, &npix);
|
||||
if(err != kCGLNoError)
|
||||
{
|
||||
log_error("Failed to choose pixel format\n");
|
||||
return -1;
|
||||
}
|
||||
err = CGLCreateContext(pix, NULL, &mCGLContext);
|
||||
if(err != kCGLNoError)
|
||||
{
|
||||
log_error("Failed to create GL context\n");
|
||||
return -1;
|
||||
}
|
||||
CGLSetCurrentContext(mCGLContext);
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (!mIsGlutInit)
|
||||
{
|
||||
// Create a GLUT window to render into
|
||||
glutInit(argc, argv);
|
||||
glutInitWindowSize(512, 512);
|
||||
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
|
||||
glutCreateWindow("OpenCL <-> OpenGL Test");
|
||||
mIsGlutInit = true;
|
||||
}
|
||||
}
|
||||
|
||||
virtual cl_context CreateCLContext( void )
|
||||
else
|
||||
{
|
||||
|
||||
CGLPixelFormatAttribute attribs[] = {
|
||||
kCGLPFAOpenGLProfile,
|
||||
(CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core,
|
||||
kCGLPFAAllowOfflineRenderers,
|
||||
kCGLPFANoRecovery,
|
||||
kCGLPFAAccelerated,
|
||||
kCGLPFADoubleBuffer,
|
||||
(CGLPixelFormatAttribute)0
|
||||
};
|
||||
|
||||
CGLError err;
|
||||
CGLPixelFormatObj pix;
|
||||
GLint npix;
|
||||
err = CGLChoosePixelFormat(attribs, &pix, &npix);
|
||||
if (err != kCGLNoError)
|
||||
{
|
||||
log_error("Failed to choose pixel format\n");
|
||||
return -1;
|
||||
}
|
||||
err = CGLCreateContext(pix, NULL, &mCGLContext);
|
||||
if (err != kCGLNoError)
|
||||
{
|
||||
log_error("Failed to create GL context\n");
|
||||
return -1;
|
||||
}
|
||||
CGLSetCurrentContext(mCGLContext);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
cl_context CreateCLContext(void) override
|
||||
{
|
||||
int error;
|
||||
|
||||
if( mCGLContext == NULL )
|
||||
mCGLContext = CGLGetCurrentContext();
|
||||
|
||||
CGLShareGroupObj share_group = CGLGetShareGroup(mCGLContext);
|
||||
cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)share_group, 0 };
|
||||
mShareGroup = CGLGetShareGroup(mCGLContext);
|
||||
cl_context_properties properties[] = {
|
||||
CL_CONTEXT_PLATFORM, (cl_context_properties)mPlatform,
|
||||
CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE,
|
||||
(cl_context_properties)mShareGroup, 0
|
||||
};
|
||||
cl_context context = clCreateContext(properties, 0, 0, 0, 0, &error);
|
||||
if (error) {
|
||||
print_error(error, "clCreateContext failed");
|
||||
@@ -108,16 +117,24 @@ public:
|
||||
return context;
|
||||
}
|
||||
|
||||
virtual int SupportsCLGLInterop( cl_device_type device_type )
|
||||
int SupportsCLGLInterop(cl_device_type device_type) override
|
||||
{
|
||||
int found_valid_device = 0;
|
||||
cl_device_id devices[64];
|
||||
cl_uint num_of_devices;
|
||||
int error;
|
||||
error = clGetDeviceIDs(NULL, device_type, 64, devices, &num_of_devices);
|
||||
error = clGetPlatformIDs(1, &mPlatform, NULL);
|
||||
if (error)
|
||||
{
|
||||
print_error(error, "clGetPlatformIDs failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
error =
|
||||
clGetDeviceIDs(mPlatform, device_type, 64, devices, &num_of_devices);
|
||||
if (error) {
|
||||
print_error(error, "clGetDeviceIDs failed");
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i=0; i<(int)num_of_devices; i++) {
|
||||
@@ -131,13 +148,11 @@ public:
|
||||
return found_valid_device;
|
||||
}
|
||||
|
||||
virtual ~OSXGLEnvironment()
|
||||
{
|
||||
CGLDestroyContext( mCGLContext );
|
||||
}
|
||||
|
||||
CGLContextObj mCGLContext;
|
||||
virtual ~OSXGLEnvironment() { CGLDestroyContext(mCGLContext); }
|
||||
|
||||
CGLContextObj mCGLContext;
|
||||
CGLShareGroupObj mShareGroup;
|
||||
cl_platform_id mPlatform;
|
||||
};
|
||||
|
||||
GLEnvironment * GLEnvironment::Instance( void )
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Copyright (c) 2024 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
|
||||
@@ -42,14 +42,19 @@ private:
|
||||
cl_platform_id m_platform;
|
||||
bool m_is_glut_init;
|
||||
|
||||
HGLRC m_hGLRC;
|
||||
HDC m_hDC;
|
||||
|
||||
public:
|
||||
WGLEnvironment()
|
||||
{
|
||||
m_device_count = 0;
|
||||
m_platform = 0;
|
||||
m_is_glut_init = false;
|
||||
m_hGLRC = 0;
|
||||
m_hDC = 0;
|
||||
}
|
||||
virtual int Init( int *argc, char **argv, int use_opengl_32 )
|
||||
int Init(int *argc, char **argv, int use_opengl_32) override
|
||||
{
|
||||
if (!m_is_glut_init)
|
||||
{
|
||||
@@ -64,21 +69,25 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual cl_context CreateCLContext( void )
|
||||
cl_context CreateCLContext(void) override
|
||||
{
|
||||
HGLRC hGLRC = wglGetCurrentContext();
|
||||
HDC hDC = wglGetCurrentDC();
|
||||
m_hGLRC = wglGetCurrentContext();
|
||||
m_hDC = wglGetCurrentDC();
|
||||
cl_context_properties properties[] = {
|
||||
CL_CONTEXT_PLATFORM, (cl_context_properties) m_platform,
|
||||
CL_GL_CONTEXT_KHR, (cl_context_properties) hGLRC,
|
||||
CL_WGL_HDC_KHR, (cl_context_properties) hDC,
|
||||
CL_CONTEXT_PLATFORM,
|
||||
(cl_context_properties)m_platform,
|
||||
CL_GL_CONTEXT_KHR,
|
||||
(cl_context_properties)m_hGLRC,
|
||||
CL_WGL_HDC_KHR,
|
||||
(cl_context_properties)m_hDC,
|
||||
0
|
||||
};
|
||||
cl_device_id devices[MAX_DEVICES];
|
||||
size_t dev_size;
|
||||
cl_int status;
|
||||
|
||||
if (!hGLRC || !hDC) {
|
||||
if (!m_hGLRC || !m_hDC)
|
||||
{
|
||||
print_error(CL_INVALID_CONTEXT, "No GL context bound");
|
||||
return 0;
|
||||
}
|
||||
@@ -155,7 +164,7 @@ public:
|
||||
return clCreateContext(properties, 1, &ctxDevice, NULL, NULL, &status);
|
||||
}
|
||||
|
||||
virtual int SupportsCLGLInterop( cl_device_type device_type )
|
||||
int SupportsCLGLInterop(cl_device_type device_type) override
|
||||
{
|
||||
cl_device_id devices[MAX_DEVICES];
|
||||
cl_uint num_of_devices;
|
||||
|
||||
@@ -28,13 +28,21 @@ private:
|
||||
cl_uint m_device_count;
|
||||
bool m_glut_init;
|
||||
|
||||
cl_platform_id m_platform;
|
||||
GLXContext m_context;
|
||||
Display *m_dpy;
|
||||
|
||||
public:
|
||||
X11GLEnvironment()
|
||||
{
|
||||
m_device_count = 0;
|
||||
m_glut_init = false;
|
||||
m_platform = 0;
|
||||
m_context = 0;
|
||||
m_dpy = nullptr;
|
||||
}
|
||||
virtual int Init( int *argc, char **argv, int use_opencl_32 )
|
||||
|
||||
int Init(int *argc, char **argv, int use_opencl_32) override
|
||||
{
|
||||
// Create a GLUT window to render into
|
||||
if (!m_glut_init)
|
||||
@@ -49,19 +57,24 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual cl_context CreateCLContext( void )
|
||||
cl_context CreateCLContext(void) override
|
||||
{
|
||||
GLXContext context = glXGetCurrentContext();
|
||||
Display *dpy = glXGetCurrentDisplay();
|
||||
m_context = glXGetCurrentContext();
|
||||
m_dpy = glXGetCurrentDisplay();
|
||||
|
||||
cl_context_properties properties[] = {
|
||||
CL_GL_CONTEXT_KHR, (cl_context_properties) context,
|
||||
CL_GLX_DISPLAY_KHR, (cl_context_properties) dpy,
|
||||
CL_CONTEXT_PLATFORM,
|
||||
(cl_context_properties)m_platform,
|
||||
CL_GL_CONTEXT_KHR,
|
||||
(cl_context_properties)m_context,
|
||||
CL_GLX_DISPLAY_KHR,
|
||||
(cl_context_properties)m_dpy,
|
||||
0
|
||||
};
|
||||
cl_int status;
|
||||
|
||||
if (!context || !dpy) {
|
||||
if (!m_context || !m_dpy)
|
||||
{
|
||||
print_error(CL_INVALID_CONTEXT, "No GL context bound");
|
||||
return 0;
|
||||
}
|
||||
@@ -69,19 +82,19 @@ public:
|
||||
return clCreateContext(properties, 1, m_devices, NULL, NULL, &status);
|
||||
}
|
||||
|
||||
virtual int SupportsCLGLInterop( cl_device_type device_type )
|
||||
int SupportsCLGLInterop(cl_device_type device_type) override
|
||||
{
|
||||
int found_valid_device = 0;
|
||||
cl_platform_id platform;
|
||||
cl_device_id devices[64];
|
||||
cl_uint num_of_devices;
|
||||
int error;
|
||||
error = clGetPlatformIDs(1, &platform, NULL);
|
||||
error = clGetPlatformIDs(1, &m_platform, NULL);
|
||||
if (error) {
|
||||
print_error(error, "clGetPlatformIDs failed");
|
||||
return -1;
|
||||
}
|
||||
error = clGetDeviceIDs(platform, device_type, 64, devices, &num_of_devices);
|
||||
error = clGetDeviceIDs(m_platform, device_type, 64, devices,
|
||||
&num_of_devices);
|
||||
// If this platform doesn't have any of the requested device_type (namely GPUs) then return 0
|
||||
if (error == CL_DEVICE_NOT_FOUND)
|
||||
return 0;
|
||||
|
||||
@@ -213,6 +213,12 @@ const char *GetChannelTypeName(cl_channel_type type)
|
||||
case CL_UNORM_INT24: return "CL_UNORM_INT24";
|
||||
case CL_UNSIGNED_INT_RAW10_EXT: return "CL_UNSIGNED_INT_RAW10_EXT";
|
||||
case CL_UNSIGNED_INT_RAW12_EXT: return "CL_UNSIGNED_INT_RAW12_EXT";
|
||||
case CL_UNSIGNED_INT10X6_EXT: return "CL_UNSIGNED_INT10X6_EXT";
|
||||
case CL_UNSIGNED_INT12X4_EXT: return "CL_UNSIGNED_INT12X4_EXT";
|
||||
case CL_UNSIGNED_INT14X2_EXT: return "CL_UNSIGNED_INT14X2_EXT";
|
||||
case CL_UNORM_INT10X6_EXT: return "CL_UNORM_INT10X6_EXT";
|
||||
case CL_UNORM_INT12X4_EXT: return "CL_UNORM_INT12X4_EXT";
|
||||
case CL_UNORM_INT14X2_EXT: return "CL_UNORM_INT14X2_EXT";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
@@ -238,10 +244,16 @@ int IsChannelTypeSupported(cl_channel_type type)
|
||||
case CL_UNSIGNED_INT16:
|
||||
case CL_UNSIGNED_INT32:
|
||||
case CL_HALF_FLOAT:
|
||||
case CL_FLOAT: return 1;
|
||||
case CL_FLOAT:
|
||||
#ifdef CL_SFIXED14_APPLE
|
||||
case CL_SFIXED14_APPLE: return 1;
|
||||
case CL_SFIXED14_APPLE:
|
||||
#endif
|
||||
case CL_UNSIGNED_INT10X6_EXT:
|
||||
case CL_UNSIGNED_INT12X4_EXT:
|
||||
case CL_UNSIGNED_INT14X2_EXT:
|
||||
case CL_UNORM_INT10X6_EXT:
|
||||
case CL_UNORM_INT12X4_EXT:
|
||||
case CL_UNORM_INT14X2_EXT: return 1;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,13 @@ uint32_t get_channel_data_type_size(cl_channel_type channelType)
|
||||
case CL_UNSIGNED_INT32: return sizeof(cl_int);
|
||||
|
||||
case CL_UNORM_SHORT_565:
|
||||
case CL_UNORM_SHORT_555: return 2;
|
||||
case CL_UNORM_SHORT_555:
|
||||
case CL_UNSIGNED_INT10X6_EXT:
|
||||
case CL_UNSIGNED_INT12X4_EXT:
|
||||
case CL_UNSIGNED_INT14X2_EXT:
|
||||
case CL_UNORM_INT10X6_EXT:
|
||||
case CL_UNORM_INT12X4_EXT:
|
||||
case CL_UNORM_INT14X2_EXT: return 2;
|
||||
|
||||
case CL_UNORM_INT_101010:
|
||||
case CL_UNORM_INT_101010_2:
|
||||
@@ -186,6 +192,12 @@ cl_channel_type get_channel_type_from_name(const char *name)
|
||||
#ifdef CL_SFIXED14_APPLE
|
||||
{ CL_SFIXED14_APPLE, "CL_SFIXED14_APPLE" }
|
||||
#endif
|
||||
{ CL_UNSIGNED_INT10X6_EXT, "CL_UNSIGNED_INT10X6_EXT" },
|
||||
{ CL_UNSIGNED_INT12X4_EXT, "CL_UNSIGNED_INT12X4_EXT" },
|
||||
{ CL_UNSIGNED_INT14X2_EXT, "CL_UNSIGNED_INT14X2_EXT" },
|
||||
{ CL_UNORM_INT10X6_EXT, "CL_UNORM_INT10X6_EXT" },
|
||||
{ CL_UNORM_INT12X4_EXT, "CL_UNORM_INT12X4_EXT" },
|
||||
{ CL_UNORM_INT14X2_EXT, "CL_UNORM_INT14X2_EXT" },
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(typeNames) / sizeof(typeNames[0]); i++)
|
||||
{
|
||||
@@ -278,6 +290,12 @@ uint32_t get_pixel_size(const cl_image_format *format)
|
||||
#ifdef CL_SFIXED14_APPLE
|
||||
case CL_SFIXED14_APPLE:
|
||||
#endif
|
||||
case CL_UNSIGNED_INT10X6_EXT:
|
||||
case CL_UNSIGNED_INT12X4_EXT:
|
||||
case CL_UNSIGNED_INT14X2_EXT:
|
||||
case CL_UNORM_INT10X6_EXT:
|
||||
case CL_UNORM_INT12X4_EXT:
|
||||
case CL_UNORM_INT14X2_EXT:
|
||||
return get_format_channel_count(format) * sizeof(cl_ushort);
|
||||
|
||||
case CL_SIGNED_INT32:
|
||||
@@ -940,6 +958,9 @@ float get_max_absolute_error(const cl_image_format *format,
|
||||
#endif
|
||||
case CL_UNORM_SHORT_555:
|
||||
case CL_UNORM_SHORT_565: return 1.0f / 31.0f;
|
||||
case CL_UNORM_INT10X6_EXT: return 1.0f / 1023.0f;
|
||||
case CL_UNORM_INT12X4_EXT: return 1.0f / 4095.0f;
|
||||
case CL_UNORM_INT14X2_EXT: return 1.0f / 16383.0f;
|
||||
default: return 0.0f;
|
||||
}
|
||||
}
|
||||
@@ -968,6 +989,9 @@ float get_max_relative_error(const cl_image_format *format,
|
||||
case CL_UNORM_INT_101010:
|
||||
case CL_UNORM_INT_101010_2:
|
||||
case CL_UNORM_INT_2_101010_EXT:
|
||||
case CL_UNORM_INT10X6_EXT:
|
||||
case CL_UNORM_INT12X4_EXT:
|
||||
case CL_UNORM_INT14X2_EXT:
|
||||
// Maximum sampling error for round to zero normalization based on
|
||||
// multiplication by reciprocal (using reciprocal generated in
|
||||
// round to +inf mode, so that 1.0 matches spec)
|
||||
@@ -1053,7 +1077,15 @@ size_t get_format_max_int(const cl_image_format *format)
|
||||
|
||||
case CL_UNORM_INT_101010:
|
||||
case CL_UNORM_INT_101010_2:
|
||||
case CL_UNORM_INT_2_101010_EXT: return 1023;
|
||||
case CL_UNORM_INT_2_101010_EXT:
|
||||
case CL_UNSIGNED_INT10X6_EXT:
|
||||
case CL_UNORM_INT10X6_EXT: return 1023;
|
||||
|
||||
case CL_UNSIGNED_INT12X4_EXT:
|
||||
case CL_UNORM_INT12X4_EXT: return 4095;
|
||||
|
||||
case CL_UNSIGNED_INT14X2_EXT:
|
||||
case CL_UNORM_INT14X2_EXT: return 16383;
|
||||
|
||||
case CL_HALF_FLOAT: return 1 << 10;
|
||||
|
||||
@@ -1087,7 +1119,13 @@ int get_format_min_int(const cl_image_format *format)
|
||||
case CL_UNORM_SHORT_555:
|
||||
case CL_UNORM_INT_101010:
|
||||
case CL_UNORM_INT_101010_2:
|
||||
case CL_UNORM_INT_2_101010_EXT: return 0;
|
||||
case CL_UNORM_INT_2_101010_EXT:
|
||||
case CL_UNSIGNED_INT10X6_EXT:
|
||||
case CL_UNSIGNED_INT12X4_EXT:
|
||||
case CL_UNSIGNED_INT14X2_EXT:
|
||||
case CL_UNORM_INT10X6_EXT:
|
||||
case CL_UNORM_INT12X4_EXT:
|
||||
case CL_UNORM_INT14X2_EXT: return 0;
|
||||
|
||||
case CL_HALF_FLOAT: return -(1 << 10);
|
||||
|
||||
@@ -1521,6 +1559,30 @@ void read_image_pixel_float(void *imageData, image_descriptor *imageInfo, int x,
|
||||
break;
|
||||
}
|
||||
|
||||
case CL_UNORM_INT10X6_EXT: {
|
||||
cl_ushort *dPtr = (cl_ushort *)ptr;
|
||||
for (i = 0; i < channelCount; i++)
|
||||
tempData[i] =
|
||||
CLAMP_FLOAT((float)((dPtr[i] >> 6) & 0x3ff) / 1023.0f);
|
||||
break;
|
||||
}
|
||||
|
||||
case CL_UNORM_INT12X4_EXT: {
|
||||
cl_ushort *dPtr = (cl_ushort *)ptr;
|
||||
for (i = 0; i < channelCount; i++)
|
||||
tempData[i] =
|
||||
CLAMP_FLOAT((float)((dPtr[i] >> 4) & 0xfff) / 4095.0f);
|
||||
break;
|
||||
}
|
||||
|
||||
case CL_UNORM_INT14X2_EXT: {
|
||||
cl_ushort *dPtr = (cl_ushort *)ptr;
|
||||
for (i = 0; i < channelCount; i++)
|
||||
tempData[i] =
|
||||
CLAMP_FLOAT((float)((dPtr[i] >> 2) & 0x3fff) / 16383.0f);
|
||||
break;
|
||||
}
|
||||
|
||||
case CL_FLOAT: {
|
||||
float *dPtr = (float *)ptr;
|
||||
for (i = 0; i < channelCount; i++) tempData[i] = (float)dPtr[i];
|
||||
@@ -2634,6 +2696,24 @@ void pack_image_pixel(unsigned int *srcVector,
|
||||
ptr[i] = (unsigned int)srcVector[i];
|
||||
break;
|
||||
}
|
||||
case CL_UNSIGNED_INT10X6_EXT: {
|
||||
unsigned short *ptr = (unsigned short *)outData;
|
||||
for (unsigned int i = 0; i < channelCount; i++)
|
||||
ptr[i] = (unsigned short)SATURATE(srcVector[i], 0, 1023) << 6;
|
||||
break;
|
||||
}
|
||||
case CL_UNSIGNED_INT12X4_EXT: {
|
||||
unsigned short *ptr = (unsigned short *)outData;
|
||||
for (unsigned int i = 0; i < channelCount; i++)
|
||||
ptr[i] = (unsigned short)SATURATE(srcVector[i], 0, 4095) << 4;
|
||||
break;
|
||||
}
|
||||
case CL_UNSIGNED_INT14X2_EXT: {
|
||||
unsigned short *ptr = (unsigned short *)outData;
|
||||
for (unsigned int i = 0; i < channelCount; i++)
|
||||
ptr[i] = (unsigned short)SATURATE(srcVector[i], 0, 16383) << 2;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -2809,6 +2889,27 @@ void pack_image_pixel(float *srcVector, const cl_image_format *imageFormat,
|
||||
| (((unsigned int)NORMALIZE(srcVector[3], 1023.f) & 1023) << 0);
|
||||
break;
|
||||
}
|
||||
case CL_UNORM_INT10X6_EXT: {
|
||||
cl_ushort *ptr = (cl_ushort *)outData;
|
||||
for (unsigned int i = 0; i < channelCount; i++)
|
||||
ptr[i] = ((cl_ushort)NORMALIZE(srcVector[i], 1023.f) & 1023)
|
||||
<< 6;
|
||||
break;
|
||||
}
|
||||
case CL_UNORM_INT12X4_EXT: {
|
||||
cl_ushort *ptr = (cl_ushort *)outData;
|
||||
for (unsigned int i = 0; i < channelCount; i++)
|
||||
ptr[i] = ((cl_ushort)NORMALIZE(srcVector[i], 4095.f) & 4095)
|
||||
<< 4;
|
||||
break;
|
||||
}
|
||||
case CL_UNORM_INT14X2_EXT: {
|
||||
cl_ushort *ptr = (cl_ushort *)outData;
|
||||
for (unsigned int i = 0; i < channelCount; i++)
|
||||
ptr[i] = ((cl_ushort)NORMALIZE(srcVector[i], 16383.f) & 16383)
|
||||
<< 2;
|
||||
break;
|
||||
}
|
||||
case CL_SIGNED_INT8: {
|
||||
cl_char *ptr = (cl_char *)outData;
|
||||
for (unsigned int i = 0; i < channelCount; i++)
|
||||
@@ -2852,6 +2953,27 @@ void pack_image_pixel(float *srcVector, const cl_image_format *imageFormat,
|
||||
CL_UINT_MAX);
|
||||
break;
|
||||
}
|
||||
case CL_UNSIGNED_INT10X6_EXT: {
|
||||
cl_ushort *ptr = (cl_ushort *)outData;
|
||||
for (unsigned int i = 0; i < channelCount; i++)
|
||||
ptr[i] = ((cl_ushort)NORMALIZE(srcVector[i], 1023.f) & 1023)
|
||||
<< 6;
|
||||
break;
|
||||
}
|
||||
case CL_UNSIGNED_INT12X4_EXT: {
|
||||
cl_ushort *ptr = (cl_ushort *)outData;
|
||||
for (unsigned int i = 0; i < channelCount; i++)
|
||||
ptr[i] = ((cl_ushort)NORMALIZE(srcVector[i], 4095.f) & 4095)
|
||||
<< 4;
|
||||
break;
|
||||
}
|
||||
case CL_UNSIGNED_INT14X2_EXT: {
|
||||
cl_ushort *ptr = (cl_ushort *)outData;
|
||||
for (unsigned int i = 0; i < channelCount; i++)
|
||||
ptr[i] = ((cl_ushort)NORMALIZE(srcVector[i], 16383.f) & 16383)
|
||||
<< 2;
|
||||
break;
|
||||
}
|
||||
#ifdef CL_SFIXED14_APPLE
|
||||
case CL_SFIXED14_APPLE: {
|
||||
cl_ushort *ptr = (cl_ushort *)outData;
|
||||
@@ -2999,6 +3121,33 @@ void pack_image_pixel_error(const float *srcVector,
|
||||
|
||||
break;
|
||||
}
|
||||
case CL_UNORM_INT10X6_EXT: {
|
||||
const cl_ushort *ptr = (const cl_ushort *)results;
|
||||
|
||||
for (unsigned int i = 0; i < channelCount; i++)
|
||||
errors[i] =
|
||||
(ptr[i] >> 6) - NORMALIZE_UNROUNDED(srcVector[i], 1023.f);
|
||||
|
||||
break;
|
||||
}
|
||||
case CL_UNORM_INT12X4_EXT: {
|
||||
const cl_ushort *ptr = (const cl_ushort *)results;
|
||||
|
||||
for (unsigned int i = 0; i < channelCount; i++)
|
||||
errors[i] =
|
||||
(ptr[i] >> 4) - NORMALIZE_UNROUNDED(srcVector[i], 4095.f);
|
||||
|
||||
break;
|
||||
}
|
||||
case CL_UNORM_INT14X2_EXT: {
|
||||
const cl_ushort *ptr = (const cl_ushort *)results;
|
||||
|
||||
for (unsigned int i = 0; i < channelCount; i++)
|
||||
errors[i] =
|
||||
(ptr[i] >> 2) - NORMALIZE_UNROUNDED(srcVector[i], 16383.f);
|
||||
|
||||
break;
|
||||
}
|
||||
case CL_SIGNED_INT8: {
|
||||
const cl_char *ptr = (const cl_char *)results;
|
||||
|
||||
@@ -3050,6 +3199,29 @@ void pack_image_pixel_error(const float *srcVector,
|
||||
CL_UINT_MAX));
|
||||
break;
|
||||
}
|
||||
case CL_UNSIGNED_INT10X6_EXT: {
|
||||
cl_ushort *ptr = (cl_ushort *)results;
|
||||
for (unsigned int i = 0; i < channelCount; i++)
|
||||
errors[i] = static_cast<float>(
|
||||
(cl_int)ptr[i] - (*((cl_int *)(&srcVector[i])) & 0xffc0));
|
||||
break;
|
||||
}
|
||||
case CL_UNSIGNED_INT12X4_EXT: {
|
||||
cl_ushort *ptr = (cl_ushort *)results;
|
||||
for (unsigned int i = 0; i < channelCount; i++)
|
||||
errors[i] = static_cast<float>(
|
||||
(cl_int)ptr[i] - (*((cl_int *)(&srcVector[i])) & 0xfff0));
|
||||
break;
|
||||
}
|
||||
case CL_UNSIGNED_INT14X2_EXT: {
|
||||
cl_ushort *ptr = (cl_ushort *)results;
|
||||
for (unsigned int i = 0; i < channelCount; i++)
|
||||
errors[i] = static_cast<float>(
|
||||
(cl_int)ptr[i]
|
||||
- (cl_int)CONVERT_UINT(srcVector[i], 16383.f,
|
||||
CL_USHRT_MAX));
|
||||
break;
|
||||
}
|
||||
#ifdef CL_SFIXED14_APPLE
|
||||
case CL_SFIXED14_APPLE: {
|
||||
const cl_ushort *ptr = (const cl_ushort *)results;
|
||||
|
||||
@@ -126,6 +126,7 @@ typedef struct
|
||||
const cl_image_format *format;
|
||||
cl_mem buffer;
|
||||
cl_mem_object_type type;
|
||||
cl_mem_flags mem_flags;
|
||||
cl_uint num_mip_levels;
|
||||
} image_descriptor;
|
||||
|
||||
@@ -447,6 +448,27 @@ void read_image_pixel(void *imageData, image_descriptor *imageInfo, int x,
|
||||
tempData[0] = (T)(hi_val | lo_val);
|
||||
break;
|
||||
}
|
||||
case CL_UNSIGNED_INT10X6_EXT: {
|
||||
cl_short *dPtr = (cl_short *)ptr;
|
||||
const size_t channelCount = get_format_channel_count(format);
|
||||
for (i = 0; i < channelCount; i++)
|
||||
tempData[i] = (dPtr[i] >> 6) & 0x3ff;
|
||||
break;
|
||||
}
|
||||
case CL_UNSIGNED_INT12X4_EXT: {
|
||||
cl_short *dPtr = (cl_short *)ptr;
|
||||
const size_t channelCount = get_format_channel_count(format);
|
||||
for (i = 0; i < channelCount; i++)
|
||||
tempData[i] = (dPtr[i] >> 4) & 0xfff;
|
||||
break;
|
||||
}
|
||||
case CL_UNSIGNED_INT14X2_EXT: {
|
||||
cl_short *dPtr = (cl_short *)ptr;
|
||||
const size_t channelCount = get_format_channel_count(format);
|
||||
for (i = 0; i < channelCount; i++)
|
||||
tempData[i] = (dPtr[i] >> 2) & 0x3fff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1328,6 +1328,12 @@ size_t get_pixel_bytes(const cl_image_format *fmt)
|
||||
case CL_SIGNED_INT8:
|
||||
case CL_UNSIGNED_INT8: return chanCount;
|
||||
|
||||
case CL_UNSIGNED_INT10X6_EXT:
|
||||
case CL_UNSIGNED_INT12X4_EXT:
|
||||
case CL_UNSIGNED_INT14X2_EXT:
|
||||
case CL_UNORM_INT10X6_EXT:
|
||||
case CL_UNORM_INT12X4_EXT:
|
||||
case CL_UNORM_INT14X2_EXT:
|
||||
case CL_SNORM_INT16:
|
||||
case CL_UNORM_INT16:
|
||||
case CL_HALF_FLOAT:
|
||||
|
||||
@@ -377,4 +377,24 @@ public:
|
||||
size_t getSize() const { return allocsize; };
|
||||
};
|
||||
|
||||
// scope guard helper to ensure proper releasing of sub devices
|
||||
struct SubDevicesScopeGuarded
|
||||
{
|
||||
SubDevicesScopeGuarded(const cl_int dev_count)
|
||||
{
|
||||
sub_devices.resize(dev_count);
|
||||
}
|
||||
~SubDevicesScopeGuarded()
|
||||
{
|
||||
for (auto &device : sub_devices)
|
||||
{
|
||||
cl_int err = clReleaseDevice(device);
|
||||
if (err != CL_SUCCESS)
|
||||
log_error("\n Releasing sub-device failed \n");
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<cl_device_id> sub_devices;
|
||||
};
|
||||
|
||||
#endif // _typeWrappers_h
|
||||
|
||||
@@ -26,6 +26,8 @@ typedef long long unsigned llu;
|
||||
|
||||
#define REDUCTION_PERCENTAGE_DEFAULT 50
|
||||
|
||||
#define BYTES_PER_WORK_ITEM 2048ULL
|
||||
|
||||
int g_repetition_count = 1;
|
||||
int g_reduction_percentage = REDUCTION_PERCENTAGE_DEFAULT;
|
||||
int g_write_allocations = 1;
|
||||
@@ -125,7 +127,7 @@ int doTest(cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
int number_of_mems_used;
|
||||
cl_ulong max_individual_allocation_size = g_max_individual_allocation_size;
|
||||
cl_ulong global_mem_size = g_global_mem_size;
|
||||
unsigned int number_of_work_items = 8192 * 32;
|
||||
unsigned int number_of_work_items;
|
||||
const bool allocate_image =
|
||||
(alloc_type != BUFFER) && (alloc_type != BUFFER_NON_BLOCKING);
|
||||
|
||||
@@ -183,12 +185,16 @@ int doTest(cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
g_reduction_percentage);
|
||||
g_max_size = (size_t)((double)g_max_size
|
||||
* (double)g_reduction_percentage / 100.0);
|
||||
number_of_work_items = 8192 * 2;
|
||||
}
|
||||
|
||||
// Round to nearest MB.
|
||||
g_max_size &= (size_t)(0xFFFFFFFFFF00000ULL);
|
||||
|
||||
// Scales the number of work-items to keep the amount of bytes processed
|
||||
// per work-item the same.
|
||||
number_of_work_items =
|
||||
std::max(g_max_size / BYTES_PER_WORK_ITEM, 8192ULL * 2ULL);
|
||||
|
||||
log_info("** Target allocation size (rounded to nearest MB) is: %llu bytes "
|
||||
"(%gMB).\n",
|
||||
llu(g_max_size), toMB(g_max_size));
|
||||
|
||||
@@ -4,6 +4,7 @@ set(${MODULE_NAME}_SOURCES
|
||||
main.cpp
|
||||
negative_platform.cpp
|
||||
negative_queue.cpp
|
||||
negative_enqueue_map_image.cpp
|
||||
test_api_consistency.cpp
|
||||
test_bool.cpp
|
||||
test_retain.cpp
|
||||
|
||||
191
test_conformance/api/negative_enqueue_map_image.cpp
Normal file
191
test_conformance/api/negative_enqueue_map_image.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
//
|
||||
// Copyright (c) 2024 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 "testBase.h"
|
||||
#include "harness/clImageHelper.h"
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
static constexpr cl_mem_object_type image_types[] = {
|
||||
CL_MEM_OBJECT_IMAGE2D, CL_MEM_OBJECT_IMAGE3D, CL_MEM_OBJECT_IMAGE2D_ARRAY,
|
||||
CL_MEM_OBJECT_IMAGE1D, CL_MEM_OBJECT_IMAGE1D_ARRAY
|
||||
};
|
||||
|
||||
REGISTER_TEST(negative_enqueue_map_image)
|
||||
{
|
||||
constexpr size_t image_dim = 32;
|
||||
|
||||
REQUIRE_EXTENSION("cl_ext_immutable_memory_objects");
|
||||
|
||||
static constexpr cl_mem_flags mem_flags[]{
|
||||
CL_MEM_IMMUTABLE_EXT | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_IMMUTABLE_EXT | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_IMMUTABLE_EXT | CL_MEM_COPY_HOST_PTR | CL_MEM_ALLOC_HOST_PTR
|
||||
};
|
||||
|
||||
static constexpr const char *mem_flags_string[]{
|
||||
"CL_MEM_IMMUTABLE_EXT | CL_MEM_USE_HOST_PTR",
|
||||
"CL_MEM_IMMUTABLE_EXT | CL_MEM_COPY_HOST_PTR",
|
||||
"CL_MEM_IMMUTABLE_EXT | CL_MEM_COPY_HOST_PTR | "
|
||||
"CL_MEM_ALLOC_HOST_PTR"
|
||||
};
|
||||
|
||||
static_assert(ARRAY_SIZE(mem_flags) == ARRAY_SIZE(mem_flags_string),
|
||||
"mem_flags and mem_flags_string must be of the same size");
|
||||
|
||||
using CLUCharPtr = std::unique_ptr<cl_uchar, decltype(&free)>;
|
||||
|
||||
for (size_t index = 0; index < ARRAY_SIZE(mem_flags); ++index)
|
||||
{
|
||||
cl_mem_flags mem_flag = mem_flags[index];
|
||||
|
||||
log_info("Testing memory flag: %s\n", mem_flags_string[index]);
|
||||
for (cl_mem_object_type image_type : image_types)
|
||||
{
|
||||
// find supported image formats
|
||||
cl_uint num_formats = 0;
|
||||
|
||||
cl_int error = clGetSupportedImageFormats(
|
||||
context, mem_flag, image_type, 0, nullptr, &num_formats);
|
||||
test_error(error,
|
||||
"clGetSupportedImageFormats failed to return supported "
|
||||
"formats");
|
||||
|
||||
std::vector<cl_image_format> formats(num_formats);
|
||||
error = clGetSupportedImageFormats(context, mem_flag, image_type,
|
||||
num_formats, formats.data(),
|
||||
nullptr);
|
||||
test_error(error,
|
||||
"clGetSupportedImageFormats failed to return supported "
|
||||
"formats");
|
||||
|
||||
clMemWrapper image;
|
||||
for (cl_image_format &fmt : formats)
|
||||
{
|
||||
log_info("Testing %s %s\n",
|
||||
GetChannelOrderName(fmt.image_channel_order),
|
||||
GetChannelTypeName(fmt.image_channel_data_type));
|
||||
|
||||
RandomSeed seed(gRandomSeed);
|
||||
size_t origin[3] = { 0, 0, 0 };
|
||||
size_t region[3] = { image_dim, image_dim, image_dim };
|
||||
switch (image_type)
|
||||
{
|
||||
case CL_MEM_OBJECT_IMAGE1D: {
|
||||
const size_t pixel_size = get_pixel_size(&fmt);
|
||||
const size_t image_size =
|
||||
image_dim * pixel_size * sizeof(cl_uchar);
|
||||
CLUCharPtr imgptr{ static_cast<cl_uchar *>(
|
||||
create_random_data(kUChar, seed,
|
||||
image_size)),
|
||||
free };
|
||||
image =
|
||||
create_image_1d(context, mem_flag, &fmt, image_dim,
|
||||
0, imgptr.get(), nullptr, &error);
|
||||
region[1] = 1;
|
||||
region[2] = 1;
|
||||
break;
|
||||
}
|
||||
case CL_MEM_OBJECT_IMAGE2D: {
|
||||
const size_t pixel_size = get_pixel_size(&fmt);
|
||||
const size_t image_size = image_dim * image_dim
|
||||
* pixel_size * sizeof(cl_uchar);
|
||||
CLUCharPtr imgptr{ static_cast<cl_uchar *>(
|
||||
create_random_data(kUChar, seed,
|
||||
image_size)),
|
||||
free };
|
||||
image =
|
||||
create_image_2d(context, mem_flag, &fmt, image_dim,
|
||||
image_dim, 0, imgptr.get(), &error);
|
||||
region[2] = 1;
|
||||
break;
|
||||
}
|
||||
case CL_MEM_OBJECT_IMAGE3D: {
|
||||
const size_t pixel_size = get_pixel_size(&fmt);
|
||||
const size_t image_size = image_dim * image_dim
|
||||
* image_dim * pixel_size * sizeof(cl_uchar);
|
||||
CLUCharPtr imgptr{ static_cast<cl_uchar *>(
|
||||
create_random_data(kUChar, seed,
|
||||
image_size)),
|
||||
free };
|
||||
image = create_image_3d(context, mem_flag, &fmt,
|
||||
image_dim, image_dim, image_dim,
|
||||
0, 0, imgptr.get(), &error);
|
||||
break;
|
||||
}
|
||||
case CL_MEM_OBJECT_IMAGE1D_ARRAY: {
|
||||
const size_t pixel_size = get_pixel_size(&fmt);
|
||||
const size_t image_size = image_dim * image_dim
|
||||
* pixel_size * sizeof(cl_uchar);
|
||||
CLUCharPtr imgptr{ static_cast<cl_uchar *>(
|
||||
create_random_data(kUChar, seed,
|
||||
image_size)),
|
||||
free };
|
||||
image = create_image_1d_array(context, mem_flag, &fmt,
|
||||
image_dim, image_dim, 0,
|
||||
0, imgptr.get(), &error);
|
||||
region[1] = 1;
|
||||
region[2] = 1;
|
||||
break;
|
||||
}
|
||||
case CL_MEM_OBJECT_IMAGE2D_ARRAY: {
|
||||
const size_t pixel_size = get_pixel_size(&fmt);
|
||||
const size_t image_size = image_dim * image_dim
|
||||
* image_dim * pixel_size * sizeof(cl_uchar);
|
||||
CLUCharPtr imgptr{ static_cast<cl_uchar *>(
|
||||
create_random_data(kUChar, seed,
|
||||
image_size)),
|
||||
free };
|
||||
image = create_image_2d_array(
|
||||
context, mem_flag, &fmt, image_dim, image_dim,
|
||||
image_dim, 0, 0, imgptr.get(), &error);
|
||||
region[2] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
test_error(error, "Failed to create image");
|
||||
|
||||
void *map = clEnqueueMapImage(
|
||||
queue, image, CL_TRUE, CL_MAP_WRITE, origin, region,
|
||||
nullptr, nullptr, 0, nullptr, nullptr, &error);
|
||||
|
||||
constexpr const char *write_err_msg =
|
||||
"clEnqueueMapImage should return CL_INVALID_OPERATION "
|
||||
"when: \"image has been created with CL_MEM_IMMUTABLE_EXT "
|
||||
"and CL_MAP_WRITE is set in map_flags\"";
|
||||
test_assert_error(map == nullptr, write_err_msg);
|
||||
test_failure_error_ret(error, CL_INVALID_OPERATION,
|
||||
write_err_msg, TEST_FAIL);
|
||||
|
||||
map = clEnqueueMapImage(queue, image, CL_TRUE,
|
||||
CL_MAP_WRITE_INVALIDATE_REGION, origin,
|
||||
region, nullptr, nullptr, 0, nullptr,
|
||||
nullptr, &error);
|
||||
|
||||
constexpr const char *write_invalidate_err_msg =
|
||||
"clEnqueueMapImage should return CL_INVALID_OPERATION "
|
||||
"when: \"image has been created with CL_MEM_IMMUTABLE_EXT "
|
||||
"and CL_MAP_WRITE_INVALIDATE_REGION is set in map_flags\"";
|
||||
test_assert_error(map == nullptr, write_invalidate_err_msg);
|
||||
test_failure_error_ret(error, CL_INVALID_OPERATION,
|
||||
write_invalidate_err_msg, TEST_FAIL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TEST_PASS;
|
||||
}
|
||||
@@ -27,24 +27,4 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
// scope guard helper to ensure proper releasing of sub devices
|
||||
struct SubDevicesScopeGuarded
|
||||
{
|
||||
SubDevicesScopeGuarded(const cl_int dev_count)
|
||||
{
|
||||
sub_devices.resize(dev_count);
|
||||
}
|
||||
~SubDevicesScopeGuarded()
|
||||
{
|
||||
for (auto &device : sub_devices)
|
||||
{
|
||||
cl_int err = clReleaseDevice(device);
|
||||
if (err != CL_SUCCESS)
|
||||
log_error("\n Releasing sub-device failed \n");
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<cl_device_id> sub_devices;
|
||||
};
|
||||
|
||||
#endif // _testBase_h
|
||||
|
||||
@@ -1243,13 +1243,6 @@ REGISTER_TEST(consistency_requirements_fp16)
|
||||
}
|
||||
else
|
||||
{
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_HALF_FP_CONFIG, sizeof(value),
|
||||
&value, nullptr);
|
||||
test_failure_error(
|
||||
error, CL_INVALID_VALUE,
|
||||
"cl_khr_fp16 is not available; CL_DEVICE_HALF_FP_CONFIG must fail "
|
||||
"with CL_INVALID_VALUE");
|
||||
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF,
|
||||
sizeof(value), &value, nullptr);
|
||||
test_error(
|
||||
|
||||
@@ -153,6 +153,8 @@ REGISTER_TEST(kernel_local_memory_size)
|
||||
"kernel local mem size failed");
|
||||
|
||||
|
||||
program.reset();
|
||||
kernel.reset();
|
||||
// Check memory needed to execute empty kernel with __local parameter with
|
||||
// setKernelArg
|
||||
if (create_single_kernel_helper(context, &program, &kernel, 1,
|
||||
@@ -225,6 +227,8 @@ REGISTER_TEST(kernel_local_memory_size)
|
||||
"kernel local mem size failed");
|
||||
|
||||
|
||||
program.reset();
|
||||
kernel.reset();
|
||||
// Check memory needed to execute kernel with __local variable and __local
|
||||
// parameter with setKernelArg
|
||||
if (create_single_kernel_helper(context, &program, &kernel, 1,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "testBase.h"
|
||||
#include "harness/typeWrappers.h"
|
||||
#include "harness/conversions.h"
|
||||
#include <vector>
|
||||
|
||||
const char *sample_single_test_kernel[] = {
|
||||
"__kernel void sample_test(__global float *src, __global int *dst)\n"
|
||||
@@ -49,6 +50,17 @@ const char *sample_const_test_kernel[] = {
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
const char *sample_image_test_kernel[] = {
|
||||
"__kernel void sample_image_test(__read_only image2d_t src, __write_only "
|
||||
"image2d_t dst)\n"
|
||||
"{\n"
|
||||
" int2 coord = (int2)(get_global_id(0), get_global_id(1));\n"
|
||||
" uint4 value = read_imageui(src, coord);\n"
|
||||
" write_imageui(dst, coord, value);\n"
|
||||
"\n"
|
||||
"}\n"
|
||||
};
|
||||
|
||||
const char *sample_const_global_test_kernel[] = {
|
||||
"__constant int addFactor = 1024;\n"
|
||||
"__kernel void sample_test(__global int *src1, __global int *dst)\n"
|
||||
@@ -631,3 +643,64 @@ REGISTER_TEST(kernel_global_constant)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
REGISTER_TEST(negative_set_immutable_memory_to_writeable_kernel_arg)
|
||||
{
|
||||
REQUIRE_EXTENSION("cl_ext_immutable_memory_objects");
|
||||
|
||||
cl_int error = CL_SUCCESS;
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernels[2];
|
||||
clMemWrapper image, buffer;
|
||||
const char *test_kernels[2] = { sample_const_test_kernel[0],
|
||||
sample_image_test_kernel[0] };
|
||||
constexpr cl_image_format formats = { CL_RGBA, CL_UNSIGNED_INT8 };
|
||||
constexpr size_t size_dim = 128;
|
||||
|
||||
// Setup the test
|
||||
error = create_single_kernel_helper(context, &program, nullptr, 2,
|
||||
test_kernels, nullptr);
|
||||
test_error(error, "Unable to build test program");
|
||||
|
||||
kernels[0] = clCreateKernel(program, "sample_test", &error);
|
||||
test_error(error, "Unable to get sample_test kernel for built program");
|
||||
|
||||
kernels[1] = clCreateKernel(program, "sample_image_test", &error);
|
||||
test_error(error,
|
||||
"Unable to get sample_image_test kernel for built program");
|
||||
|
||||
std::vector<cl_uchar> mem_data(size_dim * size_dim);
|
||||
buffer = clCreateBuffer(context, CL_MEM_IMMUTABLE_EXT | CL_MEM_USE_HOST_PTR,
|
||||
sizeof(cl_int) * size_dim, mem_data.data(), &error);
|
||||
test_error(error, "clCreateBuffer failed");
|
||||
|
||||
image = create_image_2d(context, CL_MEM_IMMUTABLE_EXT | CL_MEM_USE_HOST_PTR,
|
||||
&formats, size_dim, size_dim, 0, mem_data.data(),
|
||||
&error);
|
||||
test_error(error, "create_image_2d failed");
|
||||
|
||||
// Run the test
|
||||
error = clSetKernelArg(kernels[0], 0, sizeof(buffer), &buffer);
|
||||
test_error(error, "clSetKernelArg failed");
|
||||
|
||||
error = clSetKernelArg(kernels[0], 2, sizeof(buffer), &buffer);
|
||||
test_failure_error_ret(error, CL_INVALID_ARG_VALUE,
|
||||
"clSetKernelArg is supposed to fail "
|
||||
"with CL_INVALID_ARG_VALUE when a buffer is "
|
||||
"created with CL_MEM_IMMUTABLE_EXT is "
|
||||
"passed to a non-constant kernel argument",
|
||||
TEST_FAIL);
|
||||
|
||||
error = clSetKernelArg(kernels[1], 0, sizeof(image), &image);
|
||||
test_error(error, "clSetKernelArg failed");
|
||||
|
||||
error = clSetKernelArg(kernels[1], 1, sizeof(image), &image);
|
||||
test_failure_error_ret(error, CL_INVALID_ARG_VALUE,
|
||||
"clSetKernelArg is supposed to fail "
|
||||
"with CL_INVALID_ARG_VALUE when an image is "
|
||||
"created with CL_MEM_IMMUTABLE_EXT is "
|
||||
"passed to a write_only kernel argument",
|
||||
TEST_FAIL);
|
||||
|
||||
return TEST_PASS;
|
||||
}
|
||||
|
||||
@@ -796,6 +796,60 @@ REGISTER_TEST(get_device_info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
REGISTER_TEST(get_device_info_comparability)
|
||||
{
|
||||
int error = CL_SUCCESS;
|
||||
|
||||
// comparability test for CL_DEVICE_PLATFORM
|
||||
// 1. find platform related to device without using query
|
||||
cl_uint num_platforms = 0;
|
||||
error = clGetPlatformIDs(16, nullptr, &num_platforms);
|
||||
test_error(error, "clGetPlatformIDs failed");
|
||||
|
||||
std::vector<cl_platform_id> platforms(num_platforms);
|
||||
|
||||
error = clGetPlatformIDs(num_platforms, platforms.data(), &num_platforms);
|
||||
test_error(error, "clGetPlatformIDs failed");
|
||||
|
||||
cl_uint num_devices = 0;
|
||||
cl_platform_id comp_platform = nullptr;
|
||||
for (int p = 0; p < (int)num_platforms && comp_platform == nullptr; p++)
|
||||
{
|
||||
error = clGetDeviceIDs(platforms[p], CL_DEVICE_TYPE_ALL, 0, nullptr,
|
||||
&num_devices);
|
||||
if (error != CL_SUCCESS || num_devices == 0) continue;
|
||||
|
||||
std::vector<cl_device_id> devices(num_devices);
|
||||
error = clGetDeviceIDs(platforms[p], CL_DEVICE_TYPE_ALL, num_devices,
|
||||
devices.data(), nullptr);
|
||||
if (error != CL_SUCCESS) continue;
|
||||
|
||||
// find correct device
|
||||
for (auto did : devices)
|
||||
{
|
||||
if (did == device)
|
||||
{
|
||||
comp_platform = platforms[p];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test_error_fail(comp_platform == nullptr,
|
||||
"Test failed to locate platform for comparison!");
|
||||
|
||||
// 2. compare platforms found with and without using query
|
||||
cl_platform_id plat = nullptr;
|
||||
error =
|
||||
clGetDeviceInfo(device, CL_DEVICE_PLATFORM, sizeof(plat), &plat, NULL);
|
||||
test_error(error, "clGetDeviceInfo failed");
|
||||
|
||||
test_assert_error(plat == comp_platform,
|
||||
"Unexpected result returned by clGetDeviceInfo for "
|
||||
"CL_DEVICE_PLATFORM query");
|
||||
|
||||
return TEST_PASS;
|
||||
}
|
||||
|
||||
static const char *sample_compile_size[2] = {
|
||||
"__kernel void sample_test(__global int *src, __global int *dst)\n"
|
||||
|
||||
@@ -23,7 +23,8 @@ REGISTER_TEST(queue_flush_on_release)
|
||||
cl_int err;
|
||||
|
||||
// Create a command queue
|
||||
cl_command_queue cmd_queue = clCreateCommandQueue(context, device, 0, &err);
|
||||
clCommandQueueWrapper cmd_queue =
|
||||
clCreateCommandQueue(context, device, 0, &err);
|
||||
test_error(err, "Could not create command queue");
|
||||
|
||||
// Create a kernel
|
||||
@@ -42,7 +43,7 @@ REGISTER_TEST(queue_flush_on_release)
|
||||
test_error(err, "Could not enqueue kernel");
|
||||
|
||||
// Release the queue
|
||||
err = clReleaseCommandQueue(cmd_queue);
|
||||
cmd_queue.reset();
|
||||
|
||||
// Wait for kernel to execute since the queue must flush on release
|
||||
bool success = poll_until(2000, 50, [&event]() {
|
||||
@@ -64,11 +65,13 @@ REGISTER_TEST(multi_queue_flush_on_release)
|
||||
cl_int err;
|
||||
|
||||
// Create A command queue
|
||||
cl_command_queue queue_A = clCreateCommandQueue(context, device, 0, &err);
|
||||
clCommandQueueWrapper queue_A =
|
||||
clCreateCommandQueue(context, device, 0, &err);
|
||||
test_error(err, "Could not create command queue A");
|
||||
|
||||
// Create B command queue
|
||||
cl_command_queue queue_B = clCreateCommandQueue(context, device, 0, &err);
|
||||
clCommandQueueWrapper queue_B =
|
||||
clCreateCommandQueue(context, device, 0, &err);
|
||||
test_error(err, "Could not create command queue B");
|
||||
|
||||
// Create a kernel
|
||||
@@ -96,8 +99,7 @@ REGISTER_TEST(multi_queue_flush_on_release)
|
||||
|
||||
// Release queue_A, which performs an implicit flush to issue any previously
|
||||
// queued OpenCL commands
|
||||
err = clReleaseCommandQueue(queue_A);
|
||||
test_error(err, "clReleaseCommandQueue failed");
|
||||
queue_A.reset();
|
||||
|
||||
err = clFlush(queue_B);
|
||||
test_error(err, "clFlush failed");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Copyright (c) 2017-2025 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
|
||||
@@ -14,18 +14,14 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "testBase.h"
|
||||
#include "harness/typeWrappers.h"
|
||||
#include "harness/conversions.h"
|
||||
|
||||
const char* zero_sized_enqueue_test_kernel[] = {
|
||||
"__kernel void foo_kernel(__global int *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" dst[tid] = 1;\n"
|
||||
"\n"
|
||||
"}\n"
|
||||
};
|
||||
const char* zero_sized_enqueue_test_kernel = R"(
|
||||
__kernel void foo_kernel(__global int *dst)
|
||||
{
|
||||
int tid = get_global_id(0);
|
||||
dst[tid] = 1;
|
||||
}
|
||||
)";
|
||||
|
||||
const int bufSize = 128;
|
||||
|
||||
@@ -81,15 +77,20 @@ int test_zero_sized_enqueue_helper(cl_device_id device, cl_context context,
|
||||
output_stream =
|
||||
clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
|
||||
bufSize * sizeof(int), NULL, &error);
|
||||
test_error(error, "clCreateBuffer failed.");
|
||||
|
||||
// Initialise output buffer.
|
||||
int output_buffer_data = 0;
|
||||
error = clEnqueueFillBuffer(queue, output_stream, &output_buffer_data,
|
||||
sizeof(int), 0, sizeof(int) * bufSize, 0, NULL,
|
||||
NULL);
|
||||
test_error(error, "clEnqueueFillBuffer failed.");
|
||||
|
||||
/* Create a kernel to test with */
|
||||
if( create_single_kernel_helper( context, &program, &kernel, 1, zero_sized_enqueue_test_kernel, "foo_kernel" ) != 0 )
|
||||
if (create_single_kernel_helper(context, &program, &kernel, 1,
|
||||
&zero_sized_enqueue_test_kernel,
|
||||
"foo_kernel")
|
||||
!= 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@@ -98,6 +99,16 @@ int test_zero_sized_enqueue_helper(cl_device_id device, cl_context context,
|
||||
test_error( error, "clSetKernelArg failed." );
|
||||
|
||||
// Simple API return code tests for 1D, 2D and 3D zero sized ND range.
|
||||
error = test_zero_sized_enqueue_and_test_output_buffer(
|
||||
queue, kernel, output_stream, 1, nullptr);
|
||||
test_error(error, "1D null sized kernel enqueue failed.");
|
||||
error = test_zero_sized_enqueue_and_test_output_buffer(
|
||||
queue, kernel, output_stream, 2, nullptr);
|
||||
test_error(error, "2D null sized kernel enqueue failed.");
|
||||
error = test_zero_sized_enqueue_and_test_output_buffer(
|
||||
queue, kernel, output_stream, 3, nullptr);
|
||||
test_error(error, "3D null sized kernel enqueue failed.");
|
||||
|
||||
error = test_zero_sized_enqueue_and_test_output_buffer(
|
||||
queue, kernel, output_stream, 1, &ndrange1);
|
||||
test_error( error, "1D zero sized kernel enqueue failed." );
|
||||
@@ -156,6 +167,17 @@ int test_zero_sized_enqueue_helper(cl_device_id device, cl_context context,
|
||||
return -1;
|
||||
}
|
||||
|
||||
cl_command_type cmdtype;
|
||||
error = clGetEventInfo(ev, CL_EVENT_COMMAND_TYPE, sizeof(cmdtype), &cmdtype,
|
||||
NULL);
|
||||
test_error(error, "Failed to get event command type.");
|
||||
if (cmdtype != CL_COMMAND_NDRANGE_KERNEL)
|
||||
{
|
||||
log_error(
|
||||
"ERROR: incorrect zero sized kernel enqueue event command type.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cl_int sta;
|
||||
error = clGetEventInfo(ev, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof(cl_int), &sta, NULL);
|
||||
test_error( error, "Failed to get event status.");
|
||||
|
||||
@@ -71,6 +71,6 @@ if(APPLE)
|
||||
list(APPEND ${MODULE_NAME}_SOURCES test_queue_priority.cpp)
|
||||
endif(APPLE)
|
||||
|
||||
set_gnulike_module_compile_flags("-Wno-sign-compare -Wno-format")
|
||||
set_gnulike_module_compile_flags("-Wno-sign-compare")
|
||||
|
||||
include(../CMakeCommon.txt)
|
||||
|
||||
@@ -20,31 +20,42 @@
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <vector>
|
||||
|
||||
#include "testBase.h"
|
||||
|
||||
REGISTER_TEST(arrayreadwrite)
|
||||
static int test_arrayreadwrite_impl(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements,
|
||||
cl_mem_flags flags)
|
||||
{
|
||||
cl_uint *inptr, *outptr;
|
||||
cl_mem streams[1];
|
||||
clMemWrapper buffer;
|
||||
int num_tries = 400;
|
||||
num_elements = 1024 * 1024 * 4;
|
||||
int i, j, err;
|
||||
MTdata d;
|
||||
MTdataHolder d(gRandomSeed);
|
||||
|
||||
inptr = (cl_uint*)malloc(num_elements*sizeof(cl_uint));
|
||||
outptr = (cl_uint*)malloc(num_elements*sizeof(cl_uint));
|
||||
std::vector<cl_uint> reference_vals(num_elements);
|
||||
std::vector<cl_uint> inptr(num_elements);
|
||||
std::vector<cl_uint> outptr(num_elements);
|
||||
|
||||
// randomize data
|
||||
d = init_genrand( gRandomSeed );
|
||||
for (i=0; i<num_elements; i++)
|
||||
for (int i = 0; i < num_elements; i++)
|
||||
{
|
||||
inptr[i] = (cl_uint)(genrand_int32(d) & 0x7FFFFFFF);
|
||||
reference_vals[i] = (cl_uint)(genrand_int32(d) & 0x7FFFFFFF);
|
||||
}
|
||||
|
||||
streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE,
|
||||
sizeof(cl_uint) * num_elements, NULL, &err);
|
||||
void* host_ptr = nullptr;
|
||||
if ((flags & CL_MEM_USE_HOST_PTR) || (flags & CL_MEM_COPY_HOST_PTR))
|
||||
{
|
||||
host_ptr = inptr.data();
|
||||
}
|
||||
|
||||
cl_int err = CL_SUCCESS;
|
||||
buffer = clCreateBuffer(context, flags, sizeof(cl_uint) * num_elements,
|
||||
host_ptr, &err);
|
||||
test_error(err, "clCreateBuffer failed");
|
||||
|
||||
for (i=0; i<num_tries; i++)
|
||||
for (int i = 0; i < num_tries; i++)
|
||||
{
|
||||
int offset;
|
||||
int cb;
|
||||
@@ -58,15 +69,19 @@ REGISTER_TEST(arrayreadwrite)
|
||||
if (cb > (num_elements - offset))
|
||||
cb = num_elements - offset;
|
||||
|
||||
err = clEnqueueWriteBuffer(queue, streams[0], CL_TRUE, offset*sizeof(cl_uint), sizeof(cl_uint)*cb,&inptr[offset], 0, NULL, NULL);
|
||||
err = clEnqueueWriteBuffer(
|
||||
queue, buffer, CL_TRUE, offset * sizeof(cl_uint),
|
||||
sizeof(cl_uint) * cb, &reference_vals[offset], 0, nullptr, nullptr);
|
||||
test_error(err, "clEnqueueWriteBuffer failed");
|
||||
|
||||
err = clEnqueueReadBuffer( queue, streams[0], CL_TRUE, offset*sizeof(cl_uint), cb*sizeof(cl_uint), &outptr[offset], 0, NULL, NULL );
|
||||
err = clEnqueueReadBuffer(
|
||||
queue, buffer, CL_TRUE, offset * sizeof(cl_uint),
|
||||
cb * sizeof(cl_uint), &outptr[offset], 0, nullptr, nullptr);
|
||||
test_error(err, "clEnqueueReadBuffer failed");
|
||||
|
||||
for (j=offset; j<offset+cb; j++)
|
||||
for (int j = offset; j < offset + cb; j++)
|
||||
{
|
||||
if (inptr[j] != outptr[j])
|
||||
if (reference_vals[j] != outptr[j])
|
||||
{
|
||||
log_error("ARRAY read, write test failed\n");
|
||||
err = -1;
|
||||
@@ -78,13 +93,15 @@ REGISTER_TEST(arrayreadwrite)
|
||||
break;
|
||||
}
|
||||
|
||||
free_mtdata(d);
|
||||
clReleaseMemObject(streams[0]);
|
||||
free(inptr);
|
||||
free(outptr);
|
||||
|
||||
if (!err)
|
||||
log_info("ARRAY read, write test passed\n");
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
REGISTER_TEST(arrayreadwrite)
|
||||
{
|
||||
return test_arrayreadwrite_impl(device, context, queue, num_elements,
|
||||
CL_MEM_READ_WRITE);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
#include "testBase.h"
|
||||
|
||||
#define CL_EXIT_ERROR(cmd,format,...) \
|
||||
@@ -340,8 +342,21 @@ void CL_CALLBACK mem_obj_destructor_callback( cl_mem, void *data )
|
||||
free( data );
|
||||
}
|
||||
|
||||
// This is the main test function for the conformance test.
|
||||
REGISTER_TEST(bufferreadwriterect)
|
||||
using test_fn = int (*)(size_t, size_t[3], size_t[3], size_t, size_t[3],
|
||||
size_t[3]);
|
||||
struct TestFunctions
|
||||
{
|
||||
test_fn copy;
|
||||
test_fn read;
|
||||
test_fn write;
|
||||
};
|
||||
|
||||
static int test_bufferreadwriterect_impl(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements,
|
||||
cl_map_flags buffer_flags,
|
||||
const TestFunctions& test_functions)
|
||||
{
|
||||
gQueue = queue;
|
||||
cl_int err;
|
||||
@@ -352,7 +367,8 @@ REGISTER_TEST(bufferreadwriterect)
|
||||
// Compute a maximum buffer size based on the number of test images and the device maximum.
|
||||
cl_ulong max_mem_alloc_size = 0;
|
||||
CL_EXIT_ERROR(clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &max_mem_alloc_size, NULL),"Could not get device info");
|
||||
log_info("CL_DEVICE_MAX_MEM_ALLOC_SIZE = %llu bytes.\n", max_mem_alloc_size);
|
||||
log_info("CL_DEVICE_MAX_MEM_ALLOC_SIZE = %" PRIu64 " bytes.\n",
|
||||
max_mem_alloc_size);
|
||||
|
||||
// Confirm that the maximum allocation size is not zero.
|
||||
if (max_mem_alloc_size == 0) {
|
||||
@@ -390,7 +406,7 @@ REGISTER_TEST(bufferreadwriterect)
|
||||
// Check to see if adequately sized buffers were found.
|
||||
if (tries >= max_tries) {
|
||||
log_error("Error: Could not find random buffer sized less than "
|
||||
"%llu bytes in %zu tries.\n",
|
||||
"%" PRIu64 " bytes in %zu tries.\n",
|
||||
max_mem_alloc_size, max_tries);
|
||||
return -1;
|
||||
}
|
||||
@@ -431,7 +447,8 @@ REGISTER_TEST(bufferreadwriterect)
|
||||
memcpy(backing[i], verify[i], size_bytes);
|
||||
|
||||
// Create the CL buffer.
|
||||
buffer[i] = clCreateBuffer (context, CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE, size_bytes, backing[i], &err);
|
||||
buffer[i] =
|
||||
clCreateBuffer(context, buffer_flags, size_bytes, backing[i], &err);
|
||||
CL_EXIT_ERROR(err,"clCreateBuffer failed for buffer %u", i);
|
||||
|
||||
// Make sure buffer is cleaned up appropriately if we encounter an error in the rest of the calls.
|
||||
@@ -496,7 +513,8 @@ REGISTER_TEST(bufferreadwriterect)
|
||||
doffset[0], doffset[1], doffset[2], sregion[0],
|
||||
sregion[1], sregion[2],
|
||||
sregion[0] * sregion[1] * sregion[2]);
|
||||
if ((err = copy_region(src, soffset, sregion, dst, doffset, dregion)))
|
||||
if ((err = test_functions.copy(src, soffset, sregion, dst,
|
||||
doffset, dregion)))
|
||||
return err;
|
||||
break;
|
||||
case 1:
|
||||
@@ -506,7 +524,8 @@ REGISTER_TEST(bufferreadwriterect)
|
||||
doffset[0], doffset[1], doffset[2], sregion[0],
|
||||
sregion[1], sregion[2],
|
||||
sregion[0] * sregion[1] * sregion[2]);
|
||||
if ((err = read_verify_region(src, soffset, sregion, dst, doffset, dregion)))
|
||||
if ((err = test_functions.read(src, soffset, sregion, dst,
|
||||
doffset, dregion)))
|
||||
return err;
|
||||
break;
|
||||
case 2:
|
||||
@@ -516,7 +535,8 @@ REGISTER_TEST(bufferreadwriterect)
|
||||
doffset[0], doffset[1], doffset[2], sregion[0],
|
||||
sregion[1], sregion[2],
|
||||
sregion[0] * sregion[1] * sregion[2]);
|
||||
if ((err = write_region(src, soffset, sregion, dst, doffset, dregion)))
|
||||
if ((err = test_functions.write(src, soffset, sregion, dst,
|
||||
doffset, dregion)))
|
||||
return err;
|
||||
break;
|
||||
}
|
||||
@@ -559,3 +579,15 @@ REGISTER_TEST(bufferreadwriterect)
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
// This is the main test function for the conformance test.
|
||||
REGISTER_TEST(bufferreadwriterect)
|
||||
{
|
||||
TestFunctions test_functions;
|
||||
test_functions.copy = copy_region;
|
||||
test_functions.read = read_verify_region;
|
||||
test_functions.write = write_region;
|
||||
return test_bufferreadwriterect_impl(
|
||||
device, context, queue, num_elements,
|
||||
CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE, test_functions);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cinttypes>
|
||||
#include <vector>
|
||||
|
||||
#include "testBase.h"
|
||||
@@ -116,7 +117,8 @@ REGISTER_TEST(constant)
|
||||
err = clGetDeviceInfo(device, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE,
|
||||
sizeof(maxSize), &maxSize, 0);
|
||||
test_error(err, "Unable to get max constant buffer size");
|
||||
log_info("Device reports CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE %llu bytes.\n",
|
||||
log_info("Device reports CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE %" PRIu64
|
||||
" bytes.\n",
|
||||
maxSize);
|
||||
|
||||
// Limit test buffer size to 1/4 of CL_DEVICE_GLOBAL_MEM_SIZE
|
||||
|
||||
@@ -29,6 +29,9 @@ const cl_mem_flags flag_set[] = {
|
||||
CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_USE_HOST_PTR | CL_MEM_IMMUTABLE_EXT,
|
||||
CL_MEM_COPY_HOST_PTR | CL_MEM_IMMUTABLE_EXT,
|
||||
CL_MEM_COPY_HOST_PTR | CL_MEM_ALLOC_HOST_PTR | CL_MEM_IMMUTABLE_EXT,
|
||||
0
|
||||
};
|
||||
|
||||
@@ -37,6 +40,9 @@ const char *flag_set_names[] = {
|
||||
"CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR",
|
||||
"CL_MEM_USE_HOST_PTR",
|
||||
"CL_MEM_COPY_HOST_PTR",
|
||||
"CL_MEM_USE_HOST_PTR | CL_MEM_IMMUTABLE_EXT",
|
||||
"CL_MEM_COPY_HOST_PTR | CL_MEM_IMMUTABLE_EXT",
|
||||
"CL_MEM_COPY_HOST_PTR | CL_MEM_ALLOC_HOST_PTR | CL_MEM_IMMUTABLE_EXT",
|
||||
"0"
|
||||
};
|
||||
// clang-format on
|
||||
@@ -44,7 +50,7 @@ const char *flag_set_names[] = {
|
||||
REGISTER_TEST(enqueue_map_buffer)
|
||||
{
|
||||
int error;
|
||||
const size_t bufferSize = 256 * 256;
|
||||
constexpr size_t bufferSize = 256 * 256;
|
||||
MTdataHolder d{ gRandomSeed };
|
||||
BufferOwningPtr<cl_char> hostPtrData{ malloc(bufferSize) };
|
||||
BufferOwningPtr<cl_char> referenceData{ malloc(bufferSize) };
|
||||
@@ -57,18 +63,28 @@ REGISTER_TEST(enqueue_map_buffer)
|
||||
log_info("Testing with cl_mem_flags src: %s\n",
|
||||
flag_set_names[src_flag_id]);
|
||||
|
||||
if ((flag_set[src_flag_id] & CL_MEM_IMMUTABLE_EXT)
|
||||
&& !is_extension_available(device,
|
||||
"cl_ext_immutable_memory_objects"))
|
||||
{
|
||||
log_info("Device does not support CL_MEM_IMMUTABLE_EXT. "
|
||||
"Skipping the memory flag.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
generate_random_data(kChar, (unsigned int)bufferSize, d, hostPtrData);
|
||||
memcpy(referenceData, hostPtrData, bufferSize);
|
||||
|
||||
void *hostPtr = nullptr;
|
||||
cl_mem_flags flags = flag_set[src_flag_id];
|
||||
const bool is_immutable_buffer = flags & CL_MEM_IMMUTABLE_EXT;
|
||||
bool hasHostPtr =
|
||||
(flags & CL_MEM_USE_HOST_PTR) || (flags & CL_MEM_COPY_HOST_PTR);
|
||||
if (hasHostPtr) hostPtr = hostPtrData;
|
||||
memObject = clCreateBuffer(context, flags, bufferSize, hostPtr, &error);
|
||||
test_error(error, "Unable to create testing buffer");
|
||||
|
||||
if (!hasHostPtr)
|
||||
if (!hasHostPtr && !is_immutable_buffer)
|
||||
{
|
||||
error =
|
||||
clEnqueueWriteBuffer(queue, memObject, CL_TRUE, 0, bufferSize,
|
||||
@@ -86,7 +102,18 @@ REGISTER_TEST(enqueue_map_buffer)
|
||||
cl_char *mappedRegion = (cl_char *)clEnqueueMapBuffer(
|
||||
queue, memObject, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, offset,
|
||||
length, 0, NULL, NULL, &error);
|
||||
if (error != CL_SUCCESS)
|
||||
|
||||
// Mapping should fail if the buffer is immutable
|
||||
if (is_immutable_buffer)
|
||||
{
|
||||
test_failure_error_ret(
|
||||
error, CL_INVALID_OPERATION,
|
||||
"clEnqueueMapBuffer call was expected to fail "
|
||||
"with CL_INVALID_OPERATION",
|
||||
TEST_FAIL);
|
||||
continue;
|
||||
}
|
||||
else if (error != CL_SUCCESS)
|
||||
{
|
||||
print_error(error, "clEnqueueMapBuffer call failed");
|
||||
log_error("\tOffset: %d Length: %d\n", (int)offset,
|
||||
@@ -122,6 +149,11 @@ REGISTER_TEST(enqueue_map_buffer)
|
||||
finalData, 0, NULL, NULL);
|
||||
test_error(error, "Unable to read results");
|
||||
|
||||
if (is_immutable_buffer && !hasHostPtr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t q = 0; q < bufferSize; q++)
|
||||
{
|
||||
if (referenceData[q] != finalData[q])
|
||||
@@ -140,9 +172,10 @@ REGISTER_TEST(enqueue_map_buffer)
|
||||
REGISTER_TEST(enqueue_map_image)
|
||||
{
|
||||
int error;
|
||||
cl_image_format format = { CL_RGBA, CL_UNSIGNED_INT32 };
|
||||
const size_t imageSize = 256;
|
||||
const size_t imageDataSize = imageSize * imageSize * 4 * sizeof(cl_uint);
|
||||
constexpr cl_image_format format = { CL_RGBA, CL_UNSIGNED_INT32 };
|
||||
constexpr size_t imageSize = 256;
|
||||
constexpr size_t imageDataSize =
|
||||
imageSize * imageSize * 4 * sizeof(cl_uint);
|
||||
|
||||
PASSIVE_REQUIRE_IMAGE_SUPPORT(device)
|
||||
|
||||
@@ -158,20 +191,30 @@ REGISTER_TEST(enqueue_map_image)
|
||||
log_info("Testing with cl_mem_flags src: %s\n",
|
||||
flag_set_names[src_flag_id]);
|
||||
|
||||
if ((flag_set[src_flag_id] & CL_MEM_IMMUTABLE_EXT)
|
||||
&& !is_extension_available(device,
|
||||
"cl_ext_immutable_memory_objects"))
|
||||
{
|
||||
log_info("Device does not support CL_MEM_IMMUTABLE_EXT. "
|
||||
"Skipping the memory flag.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
generate_random_data(kUInt, (unsigned int)(imageSize * imageSize * 4),
|
||||
d, hostPtrData);
|
||||
memcpy(referenceData, hostPtrData, imageDataSize);
|
||||
|
||||
cl_mem_flags flags = flag_set[src_flag_id];
|
||||
bool is_immutable_image = flags & CL_MEM_IMMUTABLE_EXT;
|
||||
bool hasHostPtr =
|
||||
(flags & CL_MEM_USE_HOST_PTR) || (flags & CL_MEM_COPY_HOST_PTR);
|
||||
void *hostPtr = nullptr;
|
||||
if (hasHostPtr) hostPtr = hostPtrData;
|
||||
memObject = create_image_2d(context, CL_MEM_READ_WRITE | flags, &format,
|
||||
imageSize, imageSize, 0, hostPtr, &error);
|
||||
memObject = create_image_2d(context, flags, &format, imageSize,
|
||||
imageSize, 0, hostPtr, &error);
|
||||
test_error(error, "Unable to create testing buffer");
|
||||
|
||||
if (!hasHostPtr)
|
||||
if (!hasHostPtr && !is_immutable_image)
|
||||
{
|
||||
size_t write_origin[3] = { 0, 0, 0 },
|
||||
write_region[3] = { imageSize, imageSize, 1 };
|
||||
@@ -198,7 +241,17 @@ REGISTER_TEST(enqueue_map_image)
|
||||
cl_uint *mappedRegion = (cl_uint *)clEnqueueMapImage(
|
||||
queue, memObject, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, offset,
|
||||
region, &rowPitch, NULL, 0, NULL, NULL, &error);
|
||||
if (error != CL_SUCCESS)
|
||||
|
||||
if (is_immutable_image)
|
||||
{
|
||||
test_failure_error_ret(
|
||||
error, CL_INVALID_OPERATION,
|
||||
"clEnqueueMapImage call was expected to fail "
|
||||
"with CL_INVALID_OPERATION",
|
||||
TEST_FAIL);
|
||||
continue;
|
||||
}
|
||||
else if (error != CL_SUCCESS)
|
||||
{
|
||||
print_error(error, "clEnqueueMapImage call failed");
|
||||
log_error("\tOffset: %d,%d Region: %d,%d\n", (int)offset[0],
|
||||
@@ -245,6 +298,11 @@ REGISTER_TEST(enqueue_map_image)
|
||||
finalRegion, 0, 0, finalData, 0, NULL, NULL);
|
||||
test_error(error, "Unable to read results");
|
||||
|
||||
if (is_immutable_image && !hasHostPtr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t q = 0; q < imageSize * imageSize * 4; q++)
|
||||
{
|
||||
if (referenceData[q] != finalData[q])
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// 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
|
||||
@@ -20,213 +20,217 @@
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <memory>
|
||||
|
||||
#include "testBase.h"
|
||||
|
||||
static unsigned char *
|
||||
generate_rgba8_image(int w, int h, MTdata d)
|
||||
static std::unique_ptr<unsigned char[]> generate_rgba8_image(int w, int h,
|
||||
MTdata d)
|
||||
{
|
||||
unsigned char *ptr = (unsigned char*)malloc(w * h * 4);
|
||||
int i;
|
||||
std::unique_ptr<unsigned char[]> ptr{ new unsigned char[w * h * 4] };
|
||||
|
||||
for (i=0; i<w*h*4; i++)
|
||||
for (int i = 0; i < w * h * 4; i++)
|
||||
ptr[i] = (unsigned char)genrand_int32(d);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static int
|
||||
verify_rgba8_image(unsigned char *image, unsigned char *outptr, int w, int h)
|
||||
static int verify_rgba8_image(const unsigned char *image,
|
||||
const unsigned char *outptr, int w, int h)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i=0; i<w*h*4; i++)
|
||||
for (i = 0; i < w * h * 4; i++)
|
||||
{
|
||||
if (outptr[i] != image[i])
|
||||
return -1;
|
||||
if (outptr[i] != image[i]) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned short *
|
||||
generate_rgba16_image(int w, int h, MTdata d)
|
||||
static std::unique_ptr<unsigned short[]> generate_rgba16_image(int w, int h,
|
||||
MTdata d)
|
||||
{
|
||||
unsigned short *ptr = (unsigned short *)malloc(w * h * 4 * sizeof(unsigned short));
|
||||
int i;
|
||||
std::unique_ptr<unsigned short[]> ptr{ new unsigned short[w * h * 4] };
|
||||
|
||||
for (i=0; i<w*h*4; i++)
|
||||
for (int i = 0; i < w * h * 4; i++)
|
||||
ptr[i] = (unsigned short)genrand_int32(d);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static int
|
||||
verify_rgba16_image(unsigned short *image, unsigned short *outptr, int w, int h)
|
||||
static int verify_rgba16_image(const unsigned short *image,
|
||||
const unsigned short *outptr, int w, int h)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i=0; i<w*h*4; i++)
|
||||
for (i = 0; i < w * h * 4; i++)
|
||||
{
|
||||
if (outptr[i] != image[i])
|
||||
return -1;
|
||||
if (outptr[i] != image[i]) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static float *
|
||||
generate_rgbafp_image(int w, int h, MTdata d)
|
||||
static std::unique_ptr<float[]> generate_rgbafp_image(int w, int h, MTdata d)
|
||||
{
|
||||
float *ptr = (float*)malloc(w * h * 4 * sizeof(float));
|
||||
int i;
|
||||
std::unique_ptr<float[]> ptr{ new float[w * h * 4] };
|
||||
|
||||
for (i=0; i<w*h*4; i++)
|
||||
for (int i = 0; i < w * h * 4; i++)
|
||||
ptr[i] = get_random_float(-0x40000000, 0x40000000, d);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static int
|
||||
verify_rgbafp_image(float *image, float *outptr, int w, int h)
|
||||
static int verify_rgbafp_image(const float *image, const float *outptr, int w,
|
||||
int h)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i=0; i<w*h*4; i++)
|
||||
for (i = 0; i < w * h * 4; i++)
|
||||
{
|
||||
if (outptr[i] != image[i])
|
||||
return -1;
|
||||
if (outptr[i] != image[i]) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static constexpr cl_image_format image_formats[] = { { CL_RGBA, CL_UNORM_INT8 },
|
||||
{ CL_RGBA,
|
||||
CL_UNORM_INT16 },
|
||||
{ CL_RGBA, CL_FLOAT } };
|
||||
|
||||
REGISTER_TEST(imagecopy)
|
||||
static int test_imagecopy_impl(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements,
|
||||
cl_mem_flags src_image_flags)
|
||||
{
|
||||
cl_image_format img_format;
|
||||
unsigned char *rgba8_inptr, *rgba8_outptr;
|
||||
unsigned short *rgba16_inptr, *rgba16_outptr;
|
||||
float *rgbafp_inptr, *rgbafp_outptr;
|
||||
clMemWrapper streams[6];
|
||||
int img_width = 512;
|
||||
int img_height = 512;
|
||||
int i, err;
|
||||
MTdata d;
|
||||
constexpr size_t image_formats_count = ARRAY_SIZE(image_formats);
|
||||
std::unique_ptr<unsigned char[]> rgba8_inptr, rgba8_outptr;
|
||||
std::unique_ptr<unsigned short[]> rgba16_inptr, rgba16_outptr;
|
||||
std::unique_ptr<float[]> rgbafp_inptr, rgbafp_outptr;
|
||||
clMemWrapper streams[6];
|
||||
int img_width = 512;
|
||||
int img_height = 512;
|
||||
int i, err;
|
||||
MTdataHolder d(gRandomSeed);
|
||||
|
||||
PASSIVE_REQUIRE_IMAGE_SUPPORT( device )
|
||||
rgba8_inptr = generate_rgba8_image(img_width, img_height, d);
|
||||
rgba16_inptr = generate_rgba16_image(img_width, img_height, d);
|
||||
rgbafp_inptr = generate_rgbafp_image(img_width, img_height, d);
|
||||
|
||||
d = init_genrand( gRandomSeed );
|
||||
rgba8_inptr = (unsigned char *)generate_rgba8_image(img_width, img_height, d);
|
||||
rgba16_inptr = (unsigned short *)generate_rgba16_image(img_width, img_height, d);
|
||||
rgbafp_inptr = (float *)generate_rgbafp_image(img_width, img_height, d);
|
||||
free_mtdata(d); d = NULL;
|
||||
rgba8_outptr.reset(new unsigned char[4 * img_width * img_height]);
|
||||
rgba16_outptr.reset(new unsigned short[4 * img_width * img_height]);
|
||||
rgbafp_outptr.reset(new float[4 * img_width * img_height]);
|
||||
|
||||
rgba8_outptr = (unsigned char*)malloc(sizeof(unsigned char) * 4 * img_width * img_height);
|
||||
rgba16_outptr = (unsigned short*)malloc(sizeof(unsigned short) * 4 * img_width * img_height);
|
||||
rgbafp_outptr = (float*)malloc(sizeof(float) * 4 * img_width * img_height);
|
||||
|
||||
img_format.image_channel_order = CL_RGBA;
|
||||
img_format.image_channel_data_type = CL_UNORM_INT8;
|
||||
streams[0] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
|
||||
img_width, img_height, 0, NULL, &err);
|
||||
test_error(err, "create_image_2d failed");
|
||||
streams[1] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
|
||||
img_width, img_height, 0, NULL, &err);
|
||||
test_error(err, "create_image_2d failed");
|
||||
|
||||
img_format.image_channel_order = CL_RGBA;
|
||||
img_format.image_channel_data_type = CL_UNORM_INT16;
|
||||
streams[2] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
|
||||
img_width, img_height, 0, NULL, &err);
|
||||
test_error(err, "create_image_2d failed");
|
||||
streams[3] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
|
||||
img_width, img_height, 0, NULL, &err);
|
||||
test_error(err, "create_image_2d failed");
|
||||
|
||||
img_format.image_channel_order = CL_RGBA;
|
||||
img_format.image_channel_data_type = CL_FLOAT;
|
||||
streams[4] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
|
||||
img_width, img_height, 0, NULL, &err);
|
||||
test_error(err, "create_image_2d failed");
|
||||
streams[5] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
|
||||
img_width, img_height, 0, NULL, &err);
|
||||
test_error(err, "create_image_2d failed");
|
||||
|
||||
for (i=0; i<3; i++)
|
||||
for (size_t index = 0; index < image_formats_count; ++index)
|
||||
{
|
||||
void *p, *outp;
|
||||
int x, y, delta_w = img_width/8, delta_h = img_height/16;
|
||||
void *ptr = nullptr;
|
||||
if (src_image_flags & CL_MEM_USE_HOST_PTR
|
||||
|| src_image_flags & CL_MEM_COPY_HOST_PTR)
|
||||
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: ptr = rgba8_inptr.get(); break;
|
||||
case 1: ptr = rgba16_inptr.get(); break;
|
||||
case 2: ptr = rgbafp_inptr.get(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
streams[index * 2] =
|
||||
create_image_2d(context, src_image_flags, &image_formats[index],
|
||||
img_width, img_height, 0, ptr, &err);
|
||||
test_error(err, "create_image_2d failed");
|
||||
|
||||
streams[index * 2 + 1] =
|
||||
create_image_2d(context, CL_MEM_READ_WRITE, &image_formats[index],
|
||||
img_width, img_height, 0, nullptr, &err);
|
||||
test_error(err, "create_image_2d failed");
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
void *p, *outp;
|
||||
int x, y, delta_w = img_width / 8, delta_h = img_height / 16;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
p = (void *)rgba8_inptr;
|
||||
outp = (void *)rgba8_outptr;
|
||||
log_info("Testing CL_RGBA CL_UNORM_INT8\n");
|
||||
p = rgba8_inptr.get();
|
||||
outp = rgba8_outptr.get();
|
||||
log_info("Testing CL_RGBA CL_UNORM_INT8\n");
|
||||
break;
|
||||
case 1:
|
||||
p = (void *)rgba16_inptr;
|
||||
outp = (void *)rgba16_outptr;
|
||||
log_info("Testing CL_RGBA CL_UNORM_INT16\n");
|
||||
p = rgba16_inptr.get();
|
||||
outp = rgba16_outptr.get();
|
||||
log_info("Testing CL_RGBA CL_UNORM_INT16\n");
|
||||
break;
|
||||
case 2:
|
||||
p = (void *)rgbafp_inptr;
|
||||
outp = (void *)rgbafp_outptr;
|
||||
log_info("Testing CL_RGBA CL_FLOAT\n");
|
||||
p = rgbafp_inptr.get();
|
||||
outp = rgbafp_outptr.get();
|
||||
log_info("Testing CL_RGBA CL_FLOAT\n");
|
||||
break;
|
||||
}
|
||||
|
||||
size_t origin[3] = {0,0,0}, region[3] = {img_width, img_height, 1};
|
||||
err = clEnqueueWriteImage(queue, streams[i*2], CL_TRUE, origin, region, 0, 0, p, 0, NULL, NULL);
|
||||
test_error(err, "create_image_2d failed");
|
||||
size_t origin[3] = { 0, 0, 0 },
|
||||
region[3] = { img_width, img_height, 1 };
|
||||
if (!(src_image_flags & CL_MEM_USE_HOST_PTR
|
||||
|| src_image_flags & CL_MEM_COPY_HOST_PTR))
|
||||
{
|
||||
err = clEnqueueWriteImage(queue, streams[i * 2], CL_TRUE, origin,
|
||||
region, 0, 0, p, 0, nullptr, nullptr);
|
||||
test_error(err, "create_image_2d failed");
|
||||
}
|
||||
|
||||
int copy_number = 0;
|
||||
for (y=0; y<img_height; y+=delta_h)
|
||||
for (y = 0; y < img_height; y += delta_h)
|
||||
{
|
||||
for (x=0; x<img_width; x+=delta_w)
|
||||
for (x = 0; x < img_width; x += delta_w)
|
||||
{
|
||||
copy_number++;
|
||||
size_t copy_origin[3] = {x,y,0}, copy_region[3]={delta_w, delta_h, 1};
|
||||
err = clEnqueueCopyImage(queue, streams[i*2], streams[i*2+1],
|
||||
copy_origin, copy_origin, copy_region,
|
||||
0, NULL, NULL);
|
||||
if (err) {
|
||||
log_error("Copy %d (origin [%d, %d], size [%d, %d], image size [%d x %d]) Failed\n", copy_number, x, y, delta_w, delta_h, img_width, img_height);
|
||||
}
|
||||
test_error(err, "clEnqueueCopyImage failed");
|
||||
copy_number++;
|
||||
size_t copy_origin[3] = { x, y, 0 },
|
||||
copy_region[3] = { delta_w, delta_h, 1 };
|
||||
err = clEnqueueCopyImage(
|
||||
queue, streams[i * 2], streams[i * 2 + 1], copy_origin,
|
||||
copy_origin, copy_region, 0, NULL, NULL);
|
||||
if (err)
|
||||
{
|
||||
log_error("Copy %d (origin [%d, %d], size [%d, %d], image "
|
||||
"size [%d x %d]) Failed\n",
|
||||
copy_number, x, y, delta_w, delta_h, img_width,
|
||||
img_height);
|
||||
}
|
||||
test_error(err, "clEnqueueCopyImage failed");
|
||||
}
|
||||
}
|
||||
|
||||
err = clEnqueueReadImage(queue, streams[i*2+1], CL_TRUE, origin, region, 0, 0, outp, 0, NULL, NULL);
|
||||
err = clEnqueueReadImage(queue, streams[i * 2 + 1], CL_TRUE, origin,
|
||||
region, 0, 0, outp, 0, NULL, NULL);
|
||||
test_error(err, "clEnqueueReadImage failed");
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
err = verify_rgba8_image(rgba8_inptr, rgba8_outptr, img_width, img_height);
|
||||
err = verify_rgba8_image(rgba8_inptr.get(), rgba8_outptr.get(),
|
||||
img_width, img_height);
|
||||
break;
|
||||
case 1:
|
||||
err = verify_rgba16_image(rgba16_inptr, rgba16_outptr, img_width, img_height);
|
||||
err =
|
||||
verify_rgba16_image(rgba16_inptr.get(), rgba16_outptr.get(),
|
||||
img_width, img_height);
|
||||
break;
|
||||
case 2:
|
||||
err = verify_rgbafp_image(rgbafp_inptr, rgbafp_outptr, img_width, img_height);
|
||||
err =
|
||||
verify_rgbafp_image(rgbafp_inptr.get(), rgbafp_outptr.get(),
|
||||
img_width, img_height);
|
||||
break;
|
||||
}
|
||||
|
||||
if (err)
|
||||
break;
|
||||
if (err) break;
|
||||
}
|
||||
|
||||
free(rgba8_inptr);
|
||||
free(rgba16_inptr);
|
||||
free(rgbafp_inptr);
|
||||
free(rgba8_outptr);
|
||||
free(rgba16_outptr);
|
||||
free(rgbafp_outptr);
|
||||
|
||||
if (err)
|
||||
log_error("IMAGE copy test failed\n");
|
||||
else
|
||||
@@ -234,3 +238,11 @@ REGISTER_TEST(imagecopy)
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
REGISTER_TEST(imagecopy)
|
||||
{
|
||||
PASSIVE_REQUIRE_IMAGE_SUPPORT(device);
|
||||
|
||||
return test_imagecopy_impl(device, context, queue, num_elements,
|
||||
CL_MEM_READ_WRITE);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// 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
|
||||
@@ -20,213 +20,227 @@
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <memory>
|
||||
|
||||
#include "testBase.h"
|
||||
|
||||
static unsigned char *
|
||||
static std::unique_ptr<unsigned char[]>
|
||||
generate_uint8_image(unsigned num_elements, MTdata d)
|
||||
{
|
||||
unsigned char *ptr = (unsigned char*)malloc(num_elements);
|
||||
unsigned i;
|
||||
std::unique_ptr<unsigned char[]> ptr{ new unsigned char[num_elements] };
|
||||
|
||||
for (i=0; i<num_elements; i++)
|
||||
for (unsigned i = 0; i < num_elements; i++)
|
||||
ptr[i] = (unsigned char)genrand_int32(d);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static int
|
||||
verify_uint8_image(unsigned char *image, unsigned char *outptr, unsigned num_elements)
|
||||
static int verify_uint8_image(const unsigned char *image,
|
||||
const unsigned char *outptr,
|
||||
unsigned num_elements)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i=0; i<num_elements; i++)
|
||||
for (i = 0; i < num_elements; i++)
|
||||
{
|
||||
if (outptr[i] != image[i])
|
||||
return -1;
|
||||
if (outptr[i] != image[i]) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned short *
|
||||
static std::unique_ptr<unsigned short[]>
|
||||
generate_uint16_image(unsigned num_elements, MTdata d)
|
||||
{
|
||||
unsigned short *ptr = (unsigned short *)malloc(num_elements * sizeof(unsigned short));
|
||||
unsigned i;
|
||||
std::unique_ptr<unsigned short[]> ptr{ new unsigned short[num_elements] };
|
||||
|
||||
for (i=0; i<num_elements; i++)
|
||||
for (unsigned i = 0; i < num_elements; i++)
|
||||
ptr[i] = (unsigned short)genrand_int32(d);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static int
|
||||
verify_uint16_image(unsigned short *image, unsigned short *outptr, unsigned num_elements)
|
||||
static int verify_uint16_image(const unsigned short *image,
|
||||
const unsigned short *outptr,
|
||||
unsigned num_elements)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i=0; i<num_elements; i++)
|
||||
for (i = 0; i < num_elements; i++)
|
||||
{
|
||||
if (outptr[i] != image[i])
|
||||
return -1;
|
||||
if (outptr[i] != image[i]) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static float *
|
||||
generate_float_image(unsigned num_elements, MTdata d)
|
||||
static std::unique_ptr<float[]> generate_float_image(unsigned num_elements,
|
||||
MTdata d)
|
||||
{
|
||||
float *ptr = (float*)malloc(num_elements * sizeof(float));
|
||||
unsigned i;
|
||||
std::unique_ptr<float[]> ptr{ new float[num_elements] };
|
||||
|
||||
for (i=0; i<num_elements; i++)
|
||||
for (unsigned i = 0; i < num_elements; i++)
|
||||
ptr[i] = get_random_float(-0x40000000, 0x40000000, d);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static int
|
||||
verify_float_image(float *image, float *outptr, unsigned num_elements)
|
||||
static int verify_float_image(const float *image, const float *outptr,
|
||||
unsigned num_elements)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i=0; i<num_elements; i++)
|
||||
for (i = 0; i < num_elements; i++)
|
||||
{
|
||||
if (outptr[i] != image[i])
|
||||
return -1;
|
||||
if (outptr[i] != image[i]) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static constexpr cl_image_format image_formats[] = { { CL_RGBA, CL_UNORM_INT8 },
|
||||
{ CL_RGBA,
|
||||
CL_UNORM_INT16 },
|
||||
{ CL_RGBA, CL_FLOAT } };
|
||||
|
||||
REGISTER_TEST(imagecopy3d)
|
||||
static int test_imagecopy3d_impl(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements_ignored,
|
||||
cl_mem_flags src_image_flags)
|
||||
{
|
||||
cl_image_format img_format;
|
||||
unsigned char *rgba8_inptr, *rgba8_outptr;
|
||||
unsigned short *rgba16_inptr, *rgba16_outptr;
|
||||
float *rgbafp_inptr, *rgbafp_outptr;
|
||||
constexpr size_t image_formats_count = ARRAY_SIZE(image_formats);
|
||||
std::unique_ptr<unsigned char[]> rgba8_inptr, rgba8_outptr;
|
||||
std::unique_ptr<unsigned short[]> rgba16_inptr, rgba16_outptr;
|
||||
std::unique_ptr<float[]> rgbafp_inptr, rgbafp_outptr;
|
||||
clMemWrapper streams[6];
|
||||
int img_width = 128;
|
||||
int img_height = 128;
|
||||
int img_depth = 64;
|
||||
int i;
|
||||
cl_int err;
|
||||
unsigned num_elems = img_width * img_height * img_depth * 4;
|
||||
MTdata d;
|
||||
cl_int err;
|
||||
unsigned num_elements = img_width * img_height * img_depth * 4;
|
||||
MTdataHolder d(gRandomSeed);
|
||||
|
||||
PASSIVE_REQUIRE_3D_IMAGE_SUPPORT( device )
|
||||
rgba8_inptr = generate_uint8_image(num_elements, d);
|
||||
rgba16_inptr = generate_uint16_image(num_elements, d);
|
||||
rgbafp_inptr = generate_float_image(num_elements, d);
|
||||
|
||||
d = init_genrand( gRandomSeed );
|
||||
rgba8_inptr = (unsigned char *)generate_uint8_image(num_elems, d);
|
||||
rgba16_inptr = (unsigned short *)generate_uint16_image(num_elems, d);
|
||||
rgbafp_inptr = (float *)generate_float_image(num_elems, d);
|
||||
free_mtdata(d); d = NULL;
|
||||
rgba8_outptr.reset(new unsigned char[num_elements]);
|
||||
rgba16_outptr.reset(new unsigned short[num_elements]);
|
||||
rgbafp_outptr.reset(new float[num_elements]);
|
||||
|
||||
rgba8_outptr = (unsigned char *)malloc(sizeof(unsigned char) * num_elems);
|
||||
rgba16_outptr =
|
||||
(unsigned short *)malloc(sizeof(unsigned short) * num_elems);
|
||||
rgbafp_outptr = (float *)malloc(sizeof(float) * num_elems);
|
||||
|
||||
img_format.image_channel_order = CL_RGBA;
|
||||
img_format.image_channel_data_type = CL_UNORM_INT8;
|
||||
streams[0] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
|
||||
test_error(err, "create_image_3d failed");
|
||||
streams[1] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
|
||||
test_error(err, "create_image_3d failed");
|
||||
|
||||
img_format.image_channel_order = CL_RGBA;
|
||||
img_format.image_channel_data_type = CL_UNORM_INT16;
|
||||
streams[2] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
|
||||
test_error(err, "create_image_3d failed");
|
||||
streams[3] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
|
||||
test_error(err, "create_image_3d failed");
|
||||
|
||||
img_format.image_channel_order = CL_RGBA;
|
||||
img_format.image_channel_data_type = CL_FLOAT;
|
||||
streams[4] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
|
||||
test_error(err, "create_image_3d failed");
|
||||
streams[5] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
|
||||
test_error(err, "create_image_3d failed");
|
||||
|
||||
for (i=0; i<3; i++)
|
||||
for (size_t index = 0; index < image_formats_count; ++index)
|
||||
{
|
||||
void *p, *outp;
|
||||
int x, y, z, delta_w = img_width/8, delta_h = img_height/16, delta_d = img_depth/4;
|
||||
void *ptr = nullptr;
|
||||
if (src_image_flags & CL_MEM_USE_HOST_PTR
|
||||
|| src_image_flags & CL_MEM_COPY_HOST_PTR)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: ptr = rgba8_inptr.get(); break;
|
||||
case 1: ptr = rgba16_inptr.get(); break;
|
||||
case 2: ptr = rgbafp_inptr.get(); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
streams[index * 2] =
|
||||
create_image_3d(context, src_image_flags, &image_formats[index],
|
||||
img_width, img_height, img_depth, 0, 0, ptr, &err);
|
||||
test_error(err, "create_image_3d failed");
|
||||
|
||||
streams[index * 2 + 1] = create_image_3d(
|
||||
context, CL_MEM_READ_ONLY, &image_formats[index], img_width,
|
||||
img_height, img_depth, 0, 0, nullptr, &err);
|
||||
test_error(err, "create_image_3d failed");
|
||||
}
|
||||
|
||||
for (i = 0; i < image_formats_count; i++)
|
||||
{
|
||||
void *p, *outp;
|
||||
int x, y, z, delta_w = img_width / 8, delta_h = img_height / 16,
|
||||
delta_d = img_depth / 4;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
p = (void *)rgba8_inptr;
|
||||
outp = (void *)rgba8_outptr;
|
||||
p = rgba8_inptr.get();
|
||||
outp = rgba8_outptr.get();
|
||||
break;
|
||||
case 1:
|
||||
p = (void *)rgba16_inptr;
|
||||
outp = (void *)rgba16_outptr;
|
||||
p = rgba16_inptr.get();
|
||||
outp = rgba16_outptr.get();
|
||||
break;
|
||||
case 2:
|
||||
p = (void *)rgbafp_inptr;
|
||||
outp = (void *)rgbafp_outptr;
|
||||
p = rgbafp_inptr.get();
|
||||
outp = rgbafp_outptr.get();
|
||||
break;
|
||||
}
|
||||
|
||||
size_t origin[3]={0,0,0}, region[3]={img_width, img_height, img_depth};
|
||||
err = clEnqueueWriteImage(queue, streams[i*2], CL_TRUE, origin, region, 0, 0, p, 0, NULL, NULL);
|
||||
test_error(err, "clEnqueueWriteImage failed");
|
||||
|
||||
for (z=0; z<img_depth; z+=delta_d)
|
||||
size_t origin[3] = { 0, 0, 0 },
|
||||
region[3] = { img_width, img_height, img_depth };
|
||||
if (!(src_image_flags & CL_MEM_USE_HOST_PTR
|
||||
|| src_image_flags & CL_MEM_COPY_HOST_PTR))
|
||||
{
|
||||
for (y=0; y<img_height; y+=delta_h)
|
||||
{
|
||||
for (x=0; x<img_width; x+=delta_w)
|
||||
{
|
||||
origin[0] = x; origin[1] = y; origin[2] = z;
|
||||
region[0] = delta_w; region[1] = delta_h; region[2] = delta_d;
|
||||
err = clEnqueueWriteImage(queue, streams[i * 2], CL_TRUE, origin,
|
||||
region, 0, 0, p, 0, nullptr, nullptr);
|
||||
test_error(err, "clEnqueueWriteImage failed");
|
||||
}
|
||||
|
||||
err = clEnqueueCopyImage(queue, streams[i*2], streams[i*2+1], origin, origin, region, 0, NULL, NULL);
|
||||
test_error(err, "clEnqueueCopyImage failed");
|
||||
for (z = 0; z < img_depth; z += delta_d)
|
||||
{
|
||||
for (y = 0; y < img_height; y += delta_h)
|
||||
{
|
||||
for (x = 0; x < img_width; x += delta_w)
|
||||
{
|
||||
origin[0] = x;
|
||||
origin[1] = y;
|
||||
origin[2] = z;
|
||||
region[0] = delta_w;
|
||||
region[1] = delta_h;
|
||||
region[2] = delta_d;
|
||||
|
||||
err = clEnqueueCopyImage(queue, streams[i * 2],
|
||||
streams[i * 2 + 1], origin, origin,
|
||||
region, 0, NULL, NULL);
|
||||
test_error(err, "clEnqueueCopyImage failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
origin[0] = 0; origin[1] = 0; origin[2] = 0;
|
||||
region[0] = img_width; region[1] = img_height; region[2] = img_depth;
|
||||
err = clEnqueueReadImage(queue, streams[i*2+1], CL_TRUE, origin, region, 0, 0, outp, 0, NULL, NULL);
|
||||
origin[0] = 0;
|
||||
origin[1] = 0;
|
||||
origin[2] = 0;
|
||||
region[0] = img_width;
|
||||
region[1] = img_height;
|
||||
region[2] = img_depth;
|
||||
err = clEnqueueReadImage(queue, streams[i * 2 + 1], CL_TRUE, origin,
|
||||
region, 0, 0, outp, 0, NULL, NULL);
|
||||
test_error(err, "clEnqueueReadImage failed");
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
err = verify_uint8_image(rgba8_inptr, rgba8_outptr, num_elems);
|
||||
err = verify_uint8_image(rgba8_inptr.get(), rgba8_outptr.get(),
|
||||
num_elements);
|
||||
if (err) log_error("Failed uint8\n");
|
||||
break;
|
||||
case 1:
|
||||
err =
|
||||
verify_uint16_image(rgba16_inptr, rgba16_outptr, num_elems);
|
||||
err = verify_uint16_image(rgba16_inptr.get(),
|
||||
rgba16_outptr.get(), num_elements);
|
||||
if (err) log_error("Failed uint16\n");
|
||||
break;
|
||||
case 2:
|
||||
err =
|
||||
verify_float_image(rgbafp_inptr, rgbafp_outptr, num_elems);
|
||||
err = verify_float_image(rgbafp_inptr.get(),
|
||||
rgbafp_outptr.get(), num_elements);
|
||||
if (err) log_error("Failed float\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (err)
|
||||
break;
|
||||
if (err) break;
|
||||
}
|
||||
|
||||
free(rgba8_inptr);
|
||||
free(rgba16_inptr);
|
||||
free(rgbafp_inptr);
|
||||
free(rgba8_outptr);
|
||||
free(rgba16_outptr);
|
||||
free(rgbafp_outptr);
|
||||
|
||||
if (err)
|
||||
log_error("IMAGE3D copy test failed\n");
|
||||
else
|
||||
@@ -234,3 +248,11 @@ REGISTER_TEST(imagecopy3d)
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
REGISTER_TEST(imagecopy3d)
|
||||
{
|
||||
PASSIVE_REQUIRE_3D_IMAGE_SUPPORT(device);
|
||||
|
||||
return test_imagecopy3d_impl(device, context, queue, num_elements,
|
||||
CL_MEM_READ_WRITE);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
//
|
||||
#include "harness/compat.h"
|
||||
|
||||
#include <memory>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -23,16 +24,15 @@
|
||||
|
||||
#include "testBase.h"
|
||||
|
||||
static unsigned char *
|
||||
generate_rgba8_image(int w, int h, MTdata d)
|
||||
static std::unique_ptr<unsigned char[]> generate_rgba8_image(int w, int h,
|
||||
MTdata d)
|
||||
{
|
||||
unsigned char *ptr = (unsigned char*)malloc(w * h * 4);
|
||||
int i;
|
||||
std::unique_ptr<unsigned char[]> ptr{ new unsigned char[w * h * 4] };
|
||||
|
||||
for (i=0; i<w*h*4; i++)
|
||||
ptr[i] = (unsigned char)genrand_int32(d);
|
||||
for (int i = 0; i < w * h * 4; i++)
|
||||
ptr[i] = (unsigned char)genrand_int32(d);
|
||||
|
||||
return ptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -73,8 +73,8 @@ update_image_from_image(void *out, void *in, int x, int y, int w, int h, int img
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
verify_rgba8_image(unsigned char *image, unsigned char *outptr, int w, int h)
|
||||
static int verify_rgba8_image(const unsigned char *image,
|
||||
const unsigned char *outptr, int w, int h)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -91,16 +91,15 @@ verify_rgba8_image(unsigned char *image, unsigned char *outptr, int w, int h)
|
||||
}
|
||||
|
||||
|
||||
static unsigned short *
|
||||
generate_rgba16_image(int w, int h, MTdata d)
|
||||
static std::unique_ptr<unsigned short[]> generate_rgba16_image(int w, int h,
|
||||
MTdata d)
|
||||
{
|
||||
unsigned short *ptr = (unsigned short*)malloc(w * h * 4 * sizeof(unsigned short));
|
||||
int i;
|
||||
std::unique_ptr<unsigned short[]> ptr{ new unsigned short[w * h * 4] };
|
||||
|
||||
for (i=0; i<w*h*4; i++)
|
||||
ptr[i] = (unsigned short)genrand_int32(d);
|
||||
for (int i = 0; i < w * h * 4; i++)
|
||||
ptr[i] = (unsigned short)genrand_int32(d);
|
||||
|
||||
return ptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -121,8 +120,8 @@ update_rgba16_image(unsigned short *p, int x, int y, int w, int h, int img_width
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
verify_rgba16_image(unsigned short *image, unsigned short *outptr, int w, int h)
|
||||
static int verify_rgba16_image(const unsigned short *image,
|
||||
const unsigned short *outptr, int w, int h)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -139,16 +138,14 @@ verify_rgba16_image(unsigned short *image, unsigned short *outptr, int w, int h)
|
||||
}
|
||||
|
||||
|
||||
static float *
|
||||
generate_rgbafp_image(int w, int h, MTdata d)
|
||||
static std::unique_ptr<float[]> generate_rgbafp_image(int w, int h, MTdata d)
|
||||
{
|
||||
float *ptr = (float*)malloc(w * h * 4 * sizeof(float));
|
||||
int i;
|
||||
std::unique_ptr<float[]> ptr{ new float[w * h * 4] };
|
||||
|
||||
for (i=0; i<w*h*4; i++)
|
||||
ptr[i] = get_random_float(-0x40000000, 0x40000000, d);
|
||||
for (int i = 0; i < w * h * 4; i++)
|
||||
ptr[i] = get_random_float(-0x40000000, 0x40000000, d);
|
||||
|
||||
return ptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -169,8 +166,8 @@ update_rgbafp_image(float *p, int x, int y, int w, int h, int img_width, MTdata
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
verify_rgbafp_image(float *image, float *outptr, int w, int h)
|
||||
static int verify_rgbafp_image(const float *image, const float *outptr, int w,
|
||||
int h)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -186,59 +183,52 @@ verify_rgbafp_image(float *image, float *outptr, int w, int h)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static constexpr cl_image_format image_formats[] = { { CL_RGBA, CL_UNORM_INT8 },
|
||||
{ CL_RGBA,
|
||||
CL_UNORM_INT16 },
|
||||
{ CL_RGBA, CL_FLOAT } };
|
||||
|
||||
REGISTER_TEST(imagereadwrite)
|
||||
{
|
||||
cl_image_format img_format;
|
||||
unsigned char *rgba8_inptr, *rgba8_outptr;
|
||||
unsigned short *rgba16_inptr, *rgba16_outptr;
|
||||
float *rgbafp_inptr, *rgbafp_outptr;
|
||||
constexpr size_t image_formats_count = ARRAY_SIZE(image_formats);
|
||||
std::unique_ptr<unsigned char[]> rgba8_inptr, rgba8_outptr;
|
||||
std::unique_ptr<unsigned short[]> rgba16_inptr, rgba16_outptr;
|
||||
std::unique_ptr<float[]> rgbafp_inptr, rgbafp_outptr;
|
||||
clMemWrapper streams[3];
|
||||
int img_width = 512;
|
||||
int img_height = 512;
|
||||
int num_tries = 200;
|
||||
int i, j, err;
|
||||
MTdata d;
|
||||
MTdataHolder d(gRandomSeed);
|
||||
|
||||
PASSIVE_REQUIRE_IMAGE_SUPPORT( device )
|
||||
|
||||
d = init_genrand( gRandomSeed );
|
||||
rgba8_inptr = (unsigned char *)generate_rgba8_image(img_width, img_height, d);
|
||||
rgba16_inptr = (unsigned short *)generate_rgba16_image(img_width, img_height, d);
|
||||
rgbafp_inptr = (float *)generate_rgbafp_image(img_width, img_height, d);
|
||||
rgba8_inptr = generate_rgba8_image(img_width, img_height, d);
|
||||
rgba16_inptr = generate_rgba16_image(img_width, img_height, d);
|
||||
rgbafp_inptr = generate_rgbafp_image(img_width, img_height, d);
|
||||
|
||||
rgba8_outptr = (unsigned char*)malloc(sizeof(unsigned char) * 4 * img_width * img_height);
|
||||
rgba16_outptr = (unsigned short*)malloc(sizeof(unsigned short) * 4 * img_width * img_height);
|
||||
rgbafp_outptr = (float*)malloc(sizeof(float) * 4 * img_width * img_height);
|
||||
rgba8_outptr.reset(new unsigned char[4 * img_width * img_height]);
|
||||
rgba16_outptr.reset(new unsigned short[4 * img_width * img_height]);
|
||||
rgbafp_outptr.reset(new float[4 * img_width * img_height]);
|
||||
|
||||
img_format.image_channel_order = CL_RGBA;
|
||||
img_format.image_channel_data_type = CL_UNORM_INT8;
|
||||
streams[0] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
|
||||
img_width, img_height, 0, NULL, &err);
|
||||
test_error(err, "create_image_2d failed");
|
||||
|
||||
img_format.image_channel_order = CL_RGBA;
|
||||
img_format.image_channel_data_type = CL_UNORM_INT16;
|
||||
streams[1] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
|
||||
img_width, img_height, 0, NULL, &err);
|
||||
test_error(err, "create_image_2d failed");
|
||||
|
||||
img_format.image_channel_order = CL_RGBA;
|
||||
img_format.image_channel_data_type = CL_FLOAT;
|
||||
streams[2] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
|
||||
img_width, img_height, 0, NULL, &err);
|
||||
test_error(err, "create_image_2d failed");
|
||||
for (size_t index = 0; index < image_formats_count; ++index)
|
||||
{
|
||||
streams[index] =
|
||||
create_image_2d(context, CL_MEM_READ_WRITE, &image_formats[index],
|
||||
img_width, img_height, 0, NULL, &err);
|
||||
test_error(err, "create_image_2d failed");
|
||||
}
|
||||
|
||||
for (i=0; i<3; i++)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if (i == 0)
|
||||
p = (void *)rgba8_inptr;
|
||||
p = rgba8_inptr.get();
|
||||
else if (i == 1)
|
||||
p = (void *)rgba16_inptr;
|
||||
p = rgba16_inptr.get();
|
||||
else
|
||||
p = (void *)rgbafp_inptr;
|
||||
p = rgbafp_inptr.get();
|
||||
size_t origin[3] = {0,0,0}, region[3] = {img_width, img_height, 1};
|
||||
err = clEnqueueWriteImage(queue, streams[i], CL_TRUE,
|
||||
origin, region, 0, 0,
|
||||
@@ -250,7 +240,7 @@ REGISTER_TEST(imagereadwrite)
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0,j=0; i<num_tries*3; i++,j++)
|
||||
for (i = 0, j = 0; i < num_tries * image_formats_count; i++, j++)
|
||||
{
|
||||
int x = (int)get_random_float(0, img_width, d);
|
||||
int y = (int)get_random_float(0, img_height, d);
|
||||
@@ -260,10 +250,12 @@ REGISTER_TEST(imagereadwrite)
|
||||
int set_input_pitch = (int)(genrand_int32(d) & 0x01);
|
||||
int packed_update = (int)(genrand_int32(d) & 0x01);
|
||||
void *p, *outp;
|
||||
std::unique_ptr<unsigned char[]> p_rgba8;
|
||||
std::unique_ptr<unsigned short[]> p_rgba16;
|
||||
std::unique_ptr<float[]> p_rgbaf;
|
||||
int elem_size;
|
||||
|
||||
if (j == 3)
|
||||
j = 0;
|
||||
if (j == image_formats_count) j = 0;
|
||||
|
||||
switch (j)
|
||||
{
|
||||
@@ -272,45 +264,57 @@ REGISTER_TEST(imagereadwrite)
|
||||
elem_size = 4;
|
||||
if(packed_update)
|
||||
{
|
||||
p = generate_rgba8_image(w, h, d);
|
||||
update_image_from_image(rgba8_inptr, p, x, y, w, h, img_width, elem_size);
|
||||
p_rgba8 = generate_rgba8_image(w, h, d);
|
||||
p = p_rgba8.get();
|
||||
update_image_from_image(rgba8_inptr.get(), p, x, y, w, h,
|
||||
img_width, elem_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rgba8_image(rgba8_inptr, x, y, w, h, img_width, d);
|
||||
p = (void *)(rgba8_inptr + ((y * img_width + x) * 4));
|
||||
update_rgba8_image(rgba8_inptr.get(), x, y, w, h, img_width,
|
||||
d);
|
||||
p = static_cast<void *>(rgba8_inptr.get()
|
||||
+ ((y * img_width + x) * 4));
|
||||
}
|
||||
outp = (void *)rgba8_outptr;
|
||||
outp = static_cast<void *>(rgba8_outptr.get());
|
||||
break;
|
||||
case 1:
|
||||
//if ((w<=8) || (h<=8)) continue;
|
||||
elem_size = 2*4;
|
||||
if(packed_update)
|
||||
{
|
||||
p = generate_rgba16_image(w, h, d);
|
||||
update_image_from_image(rgba16_inptr, p, x, y, w, h, img_width, elem_size);
|
||||
p_rgba16 = generate_rgba16_image(w, h, d);
|
||||
p = p_rgba16.get();
|
||||
update_image_from_image(rgba16_inptr.get(), p, x, y, w, h,
|
||||
img_width, elem_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rgba16_image(rgba16_inptr, x, y, w, h, img_width, d);
|
||||
p = (void *)(rgba16_inptr + ((y * img_width + x) * 4));
|
||||
update_rgba16_image(rgba16_inptr.get(), x, y, w, h,
|
||||
img_width, d);
|
||||
p = static_cast<void *>(rgba16_inptr.get()
|
||||
+ ((y * img_width + x) * 4));
|
||||
}
|
||||
outp = (void *)rgba16_outptr;
|
||||
outp = static_cast<void *>(rgba16_outptr.get());
|
||||
break;
|
||||
case 2:
|
||||
//if ((w<=8) || (h<=8)) continue;
|
||||
elem_size = 4*4;
|
||||
if(packed_update)
|
||||
{
|
||||
p = generate_rgbafp_image(w, h, d);
|
||||
update_image_from_image(rgbafp_inptr, p, x, y, w, h, img_width, elem_size);
|
||||
p_rgbaf = generate_rgbafp_image(w, h, d);
|
||||
p = p_rgbaf.get();
|
||||
update_image_from_image(rgbafp_inptr.get(), p, x, y, w, h,
|
||||
img_width, elem_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rgbafp_image(rgbafp_inptr, x, y, w, h, img_width, d);
|
||||
p = (void *)(rgbafp_inptr + ((y * img_width + x) * 4));
|
||||
update_rgbafp_image(rgbafp_inptr.get(), x, y, w, h,
|
||||
img_width, d);
|
||||
p = static_cast<void *>(rgbafp_inptr.get()
|
||||
+ ((y * img_width + x) * 4));
|
||||
}
|
||||
outp = (void *)rgbafp_outptr;
|
||||
outp = static_cast<void *>(rgbafp_outptr.get());
|
||||
break;
|
||||
default:
|
||||
log_error("ERROR Invalid j = %d\n", j);
|
||||
@@ -358,8 +362,7 @@ REGISTER_TEST(imagereadwrite)
|
||||
|
||||
if(packed_update)
|
||||
{
|
||||
free(p);
|
||||
p = NULL;
|
||||
p = nullptr;
|
||||
}
|
||||
|
||||
memset(outp, 0x7, img_width*img_height*elem_size);
|
||||
@@ -379,7 +382,8 @@ REGISTER_TEST(imagereadwrite)
|
||||
switch (j)
|
||||
{
|
||||
case 0:
|
||||
err = verify_rgba8_image(rgba8_inptr, rgba8_outptr, img_width, img_height);
|
||||
err = verify_rgba8_image(rgba8_inptr.get(), rgba8_outptr.get(),
|
||||
img_width, img_height);
|
||||
if (err)
|
||||
{
|
||||
log_error("x=%d y=%d w=%d h=%d, pitch=%d, try=%d\n", x, y, w, h, (int)input_pitch, (int)i);
|
||||
@@ -387,7 +391,9 @@ REGISTER_TEST(imagereadwrite)
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
err = verify_rgba16_image(rgba16_inptr, rgba16_outptr, img_width, img_height);
|
||||
err =
|
||||
verify_rgba16_image(rgba16_inptr.get(), rgba16_outptr.get(),
|
||||
img_width, img_height);
|
||||
if (err)
|
||||
{
|
||||
log_error("x=%d y=%d w=%d h=%d, pitch=%d, try=%d\n", x, y, w, h, (int)input_pitch, (int)i);
|
||||
@@ -395,7 +401,9 @@ REGISTER_TEST(imagereadwrite)
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
err = verify_rgbafp_image(rgbafp_inptr, rgbafp_outptr, img_width, img_height);
|
||||
err =
|
||||
verify_rgbafp_image(rgbafp_inptr.get(), rgbafp_outptr.get(),
|
||||
img_width, img_height);
|
||||
if (err)
|
||||
{
|
||||
log_error("x=%d y=%d w=%d h=%d, pitch=%d, try=%d\n", x, y, w, h, (int)input_pitch, (int)i);
|
||||
@@ -407,14 +415,6 @@ REGISTER_TEST(imagereadwrite)
|
||||
if (err) break;
|
||||
}
|
||||
|
||||
free_mtdata(d);
|
||||
free(rgba8_inptr);
|
||||
free(rgba16_inptr);
|
||||
free(rgbafp_inptr);
|
||||
free(rgba8_outptr);
|
||||
free(rgba16_outptr);
|
||||
free(rgbafp_outptr);
|
||||
|
||||
if (!err)
|
||||
log_info("IMAGE read, write test passed\n");
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
//
|
||||
#include "harness/compat.h"
|
||||
|
||||
#include <memory>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -23,14 +24,13 @@
|
||||
|
||||
#include "testBase.h"
|
||||
|
||||
static unsigned char *
|
||||
static std::unique_ptr<unsigned char[]>
|
||||
generate_rgba8_image(int w, int h, int d, MTdata mtData)
|
||||
{
|
||||
unsigned char *ptr = (unsigned char*)malloc(w * h * d *4);
|
||||
int i;
|
||||
std::unique_ptr<unsigned char[]> ptr{ new unsigned char[w * h * d * 4] };
|
||||
|
||||
for (i=0; i<w*h*d*4; i++)
|
||||
ptr[i] = (unsigned char)genrand_int32(mtData);
|
||||
for (int i = 0; i < w * h * d * 4; i++)
|
||||
ptr[i] = (unsigned char)genrand_int32(mtData);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
@@ -77,8 +77,8 @@ update_image_from_image(void *out, void *in, int x, int y, int z, int w, int h,
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
verify_rgba8_image(unsigned char *image, unsigned char *outptr, int w, int h, int d)
|
||||
static int verify_rgba8_image(const unsigned char *image,
|
||||
const unsigned char *outptr, int w, int h, int d)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -95,14 +95,13 @@ verify_rgba8_image(unsigned char *image, unsigned char *outptr, int w, int h, in
|
||||
}
|
||||
|
||||
|
||||
static unsigned short *
|
||||
static std::unique_ptr<unsigned short[]>
|
||||
generate_rgba16_image(int w, int h, int d, MTdata mtData)
|
||||
{
|
||||
unsigned short *ptr = (unsigned short*)malloc(w * h * d * 4 * sizeof(unsigned short));
|
||||
int i;
|
||||
std::unique_ptr<unsigned short[]> ptr{ new unsigned short[w * h * d * 4] };
|
||||
|
||||
for (i=0; i<w*h*d*4; i++)
|
||||
ptr[i] = (unsigned short)genrand_int32(mtData);
|
||||
for (int i = 0; i < w * h * d * 4; i++)
|
||||
ptr[i] = (unsigned short)genrand_int32(mtData);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
@@ -127,8 +126,9 @@ update_rgba16_image(unsigned short *p, int x, int y, int z, int w, int h, int d,
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
verify_rgba16_image(unsigned short *image, unsigned short *outptr, int w, int h, int d)
|
||||
static int verify_rgba16_image(const unsigned short *image,
|
||||
const unsigned short *outptr, int w, int h,
|
||||
int d)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -145,14 +145,13 @@ verify_rgba16_image(unsigned short *image, unsigned short *outptr, int w, int h,
|
||||
}
|
||||
|
||||
|
||||
static float *
|
||||
generate_rgbafp_image(int w, int h, int d, MTdata mtData)
|
||||
static std::unique_ptr<float[]> generate_rgbafp_image(int w, int h, int d,
|
||||
MTdata mtData)
|
||||
{
|
||||
float *ptr = (float*)malloc(w * h * d *4 * sizeof(float));
|
||||
int i;
|
||||
std::unique_ptr<float[]> ptr{ new float[w * h * d * 4] };
|
||||
|
||||
for (i=0; i<w*h*d*4; i++)
|
||||
ptr[i] = get_random_float(-0x40000000, 0x40000000, mtData);
|
||||
for (int i = 0; i < w * h * d * 4; i++)
|
||||
ptr[i] = get_random_float(-0x40000000, 0x40000000, mtData);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
@@ -177,8 +176,8 @@ update_rgbafp_image(float *p, int x, int y, int z, int w, int h, int d, int img_
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
verify_rgbafp_image(float *image, float *outptr, int w, int h, int d)
|
||||
static int verify_rgbafp_image(const float *image, const float *outptr, int w,
|
||||
int h, int d)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -194,13 +193,17 @@ verify_rgbafp_image(float *image, float *outptr, int w, int h, int d)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static constexpr cl_image_format image_formats[] = { { CL_RGBA, CL_UNORM_INT8 },
|
||||
{ CL_RGBA,
|
||||
CL_UNORM_INT16 },
|
||||
{ CL_RGBA, CL_FLOAT } };
|
||||
|
||||
REGISTER_TEST(imagereadwrite3d)
|
||||
{
|
||||
cl_image_format img_format;
|
||||
unsigned char *rgba8_inptr, *rgba8_outptr;
|
||||
unsigned short *rgba16_inptr, *rgba16_outptr;
|
||||
float *rgbafp_inptr, *rgbafp_outptr;
|
||||
constexpr size_t image_formats_count = ARRAY_SIZE(image_formats);
|
||||
std::unique_ptr<unsigned char[]> rgba8_inptr, rgba8_outptr;
|
||||
std::unique_ptr<unsigned short[]> rgba16_inptr, rgba16_outptr;
|
||||
std::unique_ptr<float[]> rgbafp_inptr, rgbafp_outptr;
|
||||
clMemWrapper streams[3];
|
||||
int img_width = 64;
|
||||
int img_height = 64;
|
||||
@@ -208,44 +211,41 @@ REGISTER_TEST(imagereadwrite3d)
|
||||
int img_slice = img_width * img_height;
|
||||
int num_tries = 30;
|
||||
int i, j, err;
|
||||
MTdata mtData;
|
||||
MTdataHolder mtData(gRandomSeed);
|
||||
|
||||
PASSIVE_REQUIRE_3D_IMAGE_SUPPORT( device )
|
||||
|
||||
mtData = init_genrand( gRandomSeed );
|
||||
rgba8_inptr = (unsigned char *)generate_rgba8_image(img_width, img_height, img_depth, mtData);
|
||||
rgba16_inptr = (unsigned short *)generate_rgba16_image(img_width, img_height, img_depth, mtData);
|
||||
rgbafp_inptr = (float *)generate_rgbafp_image(img_width, img_height, img_depth, mtData);
|
||||
rgba8_inptr =
|
||||
generate_rgba8_image(img_width, img_height, img_depth, mtData);
|
||||
rgba16_inptr =
|
||||
generate_rgba16_image(img_width, img_height, img_depth, mtData);
|
||||
rgbafp_inptr =
|
||||
generate_rgbafp_image(img_width, img_height, img_depth, mtData);
|
||||
|
||||
rgba8_outptr = (unsigned char*)malloc(sizeof(unsigned char) * 4 * img_width * img_height * img_depth);
|
||||
rgba16_outptr = (unsigned short*)malloc(sizeof(unsigned short) * 4 * img_width * img_height * img_depth);
|
||||
rgbafp_outptr = (float*)malloc(sizeof(float) * 4 * img_width * img_height * img_depth);
|
||||
rgba8_outptr.reset(
|
||||
new unsigned char[4 * img_width * img_height * img_depth]);
|
||||
rgba16_outptr.reset(
|
||||
new unsigned short[4 * img_width * img_height * img_depth]);
|
||||
rgbafp_outptr.reset(new float[4 * img_width * img_height * img_depth]);
|
||||
|
||||
img_format.image_channel_order = CL_RGBA;
|
||||
img_format.image_channel_data_type = CL_UNORM_INT8;
|
||||
streams[0] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
|
||||
test_error(err, "create_image_3d failed");
|
||||
for (size_t index = 0; index < image_formats_count; ++index)
|
||||
{
|
||||
streams[index] = create_image_3d(
|
||||
context, CL_MEM_READ_ONLY, &image_formats[index], img_width,
|
||||
img_height, img_depth, 0, 0, nullptr, &err);
|
||||
test_error(err, "create_image_3d failed");
|
||||
}
|
||||
|
||||
img_format.image_channel_order = CL_RGBA;
|
||||
img_format.image_channel_data_type = CL_UNORM_INT16;
|
||||
streams[1] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
|
||||
test_error(err, "create_image_3d failed");
|
||||
|
||||
img_format.image_channel_order = CL_RGBA;
|
||||
img_format.image_channel_data_type = CL_FLOAT;
|
||||
streams[2] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
|
||||
test_error(err, "create_image_3d failed");
|
||||
|
||||
for (i=0; i<3; i++)
|
||||
for (i = 0; i < image_formats_count; i++)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if (i == 0)
|
||||
p = (void *)rgba8_inptr;
|
||||
p = rgba8_inptr.get();
|
||||
else if (i == 1)
|
||||
p = (void *)rgba16_inptr;
|
||||
p = rgba16_inptr.get();
|
||||
else
|
||||
p = (void *)rgbafp_inptr;
|
||||
p = rgbafp_inptr.get();
|
||||
|
||||
size_t origin[3] = {0,0,0}, region[3] = {img_width, img_height, img_depth};
|
||||
err = clEnqueueWriteImage(queue, streams[i], CL_TRUE,
|
||||
@@ -255,7 +255,7 @@ REGISTER_TEST(imagereadwrite3d)
|
||||
test_error(err, "clEnqueueWriteImage failed");
|
||||
}
|
||||
|
||||
for (i=0,j=0; i<num_tries*3; i++,j++)
|
||||
for (i = 0, j = 0; i < num_tries * image_formats_count; i++, j++)
|
||||
{
|
||||
int x = (int)get_random_float(0, (float)img_width - 1, mtData);
|
||||
int y = (int)get_random_float(0, (float)img_height - 1, mtData);
|
||||
@@ -267,10 +267,12 @@ REGISTER_TEST(imagereadwrite3d)
|
||||
int set_input_pitch = (int)(genrand_int32(mtData) & 0x01);
|
||||
int packed_update = (int)(genrand_int32(mtData) & 0x01);
|
||||
void *p, *outp;
|
||||
std::unique_ptr<unsigned char[]> p_rgba8;
|
||||
std::unique_ptr<unsigned short[]> p_rgba16;
|
||||
std::unique_ptr<float[]> p_rgbaf;
|
||||
int elem_size;
|
||||
|
||||
if (j == 3)
|
||||
j = 0;
|
||||
if (j == image_formats_count) j = 0;
|
||||
|
||||
// packed: the source image for the write is a whole image .
|
||||
// unpacked: the source image for the write is a subset within a larger image
|
||||
@@ -280,43 +282,64 @@ REGISTER_TEST(imagereadwrite3d)
|
||||
elem_size = 4;
|
||||
if(packed_update)
|
||||
{
|
||||
p = generate_rgba8_image(w, h, d, mtData);
|
||||
update_image_from_image(rgba8_inptr, p, x, y, z, w, h, d, img_width, img_height, img_depth, elem_size);
|
||||
p_rgba8 = generate_rgba8_image(w, h, d, mtData);
|
||||
p = p_rgba8.get();
|
||||
update_image_from_image(rgba8_inptr.get(), p, x, y, z, w, h,
|
||||
d, img_width, img_height, img_depth,
|
||||
elem_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rgba8_image(rgba8_inptr, x, y, z, w, h, d, img_width, img_height, img_depth, mtData);
|
||||
p = (void *)(rgba8_inptr + ((z * img_slice + y * img_width + x) * 4));
|
||||
update_rgba8_image(rgba8_inptr.get(), x, y, z, w, h, d,
|
||||
img_width, img_height, img_depth,
|
||||
mtData);
|
||||
p = static_cast<void *>(
|
||||
rgba8_inptr.get()
|
||||
+ ((z * img_slice + y * img_width + x) * 4));
|
||||
}
|
||||
outp = (void *)rgba8_outptr;
|
||||
outp = static_cast<void *>(rgba8_outptr.get());
|
||||
break;
|
||||
case 1:
|
||||
elem_size = 2*4;
|
||||
if(packed_update)
|
||||
{
|
||||
p = generate_rgba16_image(w, h, d, mtData);
|
||||
update_image_from_image(rgba16_inptr, p, x, y, z, w, h, d, img_width, img_height, img_depth, elem_size);
|
||||
p_rgba16 = generate_rgba16_image(w, h, d, mtData);
|
||||
p = p_rgba16.get();
|
||||
update_image_from_image(rgba16_inptr.get(), p, x, y, z, w,
|
||||
h, d, img_width, img_height,
|
||||
img_depth, elem_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rgba16_image(rgba16_inptr, x, y, z, w, h, d, img_width, img_height, img_depth, mtData);
|
||||
p = (void *)(rgba16_inptr + ((z * img_slice + y * img_width + x) * 4));
|
||||
update_rgba16_image(rgba16_inptr.get(), x, y, z, w, h, d,
|
||||
img_width, img_height, img_depth,
|
||||
mtData);
|
||||
p = static_cast<void *>(
|
||||
rgba16_inptr.get()
|
||||
+ ((z * img_slice + y * img_width + x) * 4));
|
||||
}
|
||||
outp = (void *)rgba16_outptr;
|
||||
outp = static_cast<void *>(rgba16_outptr.get());
|
||||
break;
|
||||
case 2:
|
||||
elem_size = 4*4;
|
||||
if(packed_update)
|
||||
{
|
||||
p = generate_rgbafp_image(w, h, d, mtData);
|
||||
update_image_from_image(rgbafp_inptr, p, x, y, z, w, h, d, img_width, img_height, img_depth, elem_size);
|
||||
p_rgbaf = generate_rgbafp_image(w, h, d, mtData);
|
||||
p = p_rgbaf.get();
|
||||
update_image_from_image(rgbafp_inptr.get(), p, x, y, z, w,
|
||||
h, d, img_width, img_height,
|
||||
img_depth, elem_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
update_rgbafp_image(rgbafp_inptr, x, y, z, w, h, d, img_width, img_height, img_depth, mtData);
|
||||
p = (void *)(rgbafp_inptr + ((z * img_slice + y * img_width + x) * 4));
|
||||
update_rgbafp_image(rgbafp_inptr.get(), x, y, z, w, h, d,
|
||||
img_width, img_height, img_depth,
|
||||
mtData);
|
||||
p = static_cast<void *>(
|
||||
rgbafp_inptr.get()
|
||||
+ ((z * img_slice + y * img_width + x) * 4));
|
||||
}
|
||||
outp = (void *)rgbafp_outptr;
|
||||
outp = static_cast<void *>(rgbafp_outptr.get());
|
||||
break;
|
||||
default:
|
||||
log_error("ERROR Invalid j = %d\n", j);
|
||||
@@ -360,8 +383,7 @@ REGISTER_TEST(imagereadwrite3d)
|
||||
|
||||
if(packed_update)
|
||||
{
|
||||
free(p);
|
||||
p = NULL;
|
||||
p = nullptr;
|
||||
}
|
||||
|
||||
memset(outp, 0x7, img_width*img_height*img_depth*elem_size);
|
||||
@@ -375,7 +397,8 @@ REGISTER_TEST(imagereadwrite3d)
|
||||
switch (j)
|
||||
{
|
||||
case 0:
|
||||
err = verify_rgba8_image(rgba8_inptr, rgba8_outptr, img_width, img_height, img_depth);
|
||||
err = verify_rgba8_image(rgba8_inptr.get(), rgba8_outptr.get(),
|
||||
img_width, img_height, img_depth);
|
||||
if (err)
|
||||
{
|
||||
log_error("x=%d y=%d z=%d w=%d h=%d d=%d pitch=%d, slice_pitch=%d, try=%d\n", x, y, z, w, h, d, (int)input_pitch, (int)input_slice_pitch, (int)i);
|
||||
@@ -383,7 +406,9 @@ REGISTER_TEST(imagereadwrite3d)
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
err = verify_rgba16_image(rgba16_inptr, rgba16_outptr, img_width, img_height, img_depth);
|
||||
err =
|
||||
verify_rgba16_image(rgba16_inptr.get(), rgba16_outptr.get(),
|
||||
img_width, img_height, img_depth);
|
||||
if (err)
|
||||
{
|
||||
log_error("x=%d y=%d z=%d w=%d h=%d d=%d pitch=%d, slice_pitch=%d, try=%d\n", x, y, z, w, h, d, (int)input_pitch, (int)input_slice_pitch, (int)i);
|
||||
@@ -391,7 +416,9 @@ REGISTER_TEST(imagereadwrite3d)
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
err = verify_rgbafp_image(rgbafp_inptr, rgbafp_outptr, img_width, img_height, img_depth);
|
||||
err =
|
||||
verify_rgbafp_image(rgbafp_inptr.get(), rgbafp_outptr.get(),
|
||||
img_width, img_height, img_depth);
|
||||
if (err)
|
||||
{
|
||||
log_error("x=%d y=%d z=%d w=%d h=%d d=%d pitch=%d, slice_pitch=%d, try=%d\n", x, y, z, w, h, d, (int)input_pitch, (int)input_slice_pitch, (int)i);
|
||||
@@ -404,14 +431,6 @@ REGISTER_TEST(imagereadwrite3d)
|
||||
break;
|
||||
}
|
||||
|
||||
free_mtdata(mtData);
|
||||
free(rgba8_inptr);
|
||||
free(rgba16_inptr);
|
||||
free(rgbafp_inptr);
|
||||
free(rgba8_outptr);
|
||||
free(rgba16_outptr);
|
||||
free(rgbafp_outptr);
|
||||
|
||||
if (!err)
|
||||
log_info("IMAGE read, write test passed\n");
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
#include <cinttypes>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -182,13 +183,13 @@ static int test_intmath(cl_device_id device, cl_context context,
|
||||
if (r != output[i])
|
||||
{
|
||||
log_error("\n\nverification failed at index %d\n", i);
|
||||
log_error("-> inputs: %llu, %llu, %llu\n",
|
||||
static_cast<cl_uint>(inputA[i]),
|
||||
static_cast<cl_uint>(inputB[i]),
|
||||
static_cast<cl_uint>(inputC[i]));
|
||||
log_error("-> expected %llu, got %llu\n\n",
|
||||
static_cast<cl_uint>(r),
|
||||
static_cast<cl_uint>(output[i]));
|
||||
log_error("-> inputs: %" PRIu64 "%" PRIu64 "%" PRIu64 "\n",
|
||||
static_cast<cl_ulong>(inputA[i]),
|
||||
static_cast<cl_ulong>(inputB[i]),
|
||||
static_cast<cl_ulong>(inputC[i]));
|
||||
log_error("-> expected %" PRIu64 "%" PRIu64 "\n\n",
|
||||
static_cast<cl_ulong>(r),
|
||||
static_cast<cl_ulong>(output[i]));
|
||||
return TEST_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
#include "harness/conversions.h"
|
||||
#include "harness/typeWrappers.h"
|
||||
#include "harness/errorHelpers.h"
|
||||
@@ -315,9 +317,14 @@ static int test_kernel_memory_alignment(cl_device_id device, cl_context context,
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if ((results_data[i] & alignments[i]) != 0) {
|
||||
total_errors++;
|
||||
log_error("\tVector size %d failed: 0x%llx is not properly aligned.\n", 1 << i, results_data[i]);
|
||||
log_error("\tVector size %d failed: 0x%" PRIx64
|
||||
" is not properly aligned.\n",
|
||||
1 << i, results_data[i]);
|
||||
} else {
|
||||
if (DEBUG) log_info("\tVector size %d passed: 0x%llx is properly aligned.\n", 1 << i, results_data[i]);
|
||||
if (DEBUG)
|
||||
log_info("\tVector size %d passed: 0x%" PRIx64
|
||||
" is properly aligned.\n",
|
||||
1 << i, results_data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -328,9 +335,14 @@ static int test_kernel_memory_alignment(cl_device_id device, cl_context context,
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if ((results_data_no_long[i] & alignments[i]) != 0) {
|
||||
total_errors++;
|
||||
log_error("\tVector size %d failed: 0x%llx is not properly aligned.\n", 1 << i, results_data_no_long[i]);
|
||||
log_error("\tVector size %d failed: 0x%x is not "
|
||||
"properly aligned.\n",
|
||||
1 << i, results_data_no_long[i]);
|
||||
} else {
|
||||
if (DEBUG) log_info("\tVector size %d passed: 0x%llx is properly aligned.\n", 1 << i, results_data_no_long[i]);
|
||||
if (DEBUG)
|
||||
log_info("\tVector size %d passed: 0x%x is "
|
||||
"properly aligned.\n",
|
||||
1 << i, results_data_no_long[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -383,9 +395,14 @@ static int test_kernel_memory_alignment(cl_device_id device, cl_context context,
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if ((results_data[i] & alignments[i]) != 0) {
|
||||
total_errors++;
|
||||
log_error("\tVector size %d failed: 0x%llx is not properly aligned.\n", 1 << i, results_data[i]);
|
||||
log_error("\tVector size %d failed: 0x%" PRIx64
|
||||
" is not properly aligned.\n",
|
||||
1 << i, results_data[i]);
|
||||
} else {
|
||||
if (DEBUG) log_info("\tVector size %d passed: 0x%llx is properly aligned.\n", 1 << i, results_data[i]);
|
||||
if (DEBUG)
|
||||
log_info("\tVector size %d passed: 0x%" PRIx64
|
||||
" is properly aligned.\n",
|
||||
1 << i, results_data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -396,9 +413,14 @@ static int test_kernel_memory_alignment(cl_device_id device, cl_context context,
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if ((results_data_no_long[i] & alignments[i]) != 0) {
|
||||
total_errors++;
|
||||
log_error("\tVector size %d failed: 0x%llx is not properly aligned.\n", 1 << i, results_data_no_long[i]);
|
||||
log_error("\tVector size %d failed: 0x%x is not "
|
||||
"properly aligned.\n",
|
||||
1 << i, results_data_no_long[i]);
|
||||
} else {
|
||||
if (DEBUG) log_info("\tVector size %d passed: 0x%llx is properly aligned.\n", 1 << i, results_data_no_long[i]);
|
||||
if (DEBUG)
|
||||
log_info("\tVector size %d passed: 0x%x is "
|
||||
"properly aligned.\n",
|
||||
1 << i, results_data_no_long[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -455,9 +477,14 @@ static int test_kernel_memory_alignment(cl_device_id device, cl_context context,
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if ((results_data[i] & alignments[i]) != 0) {
|
||||
total_errors++;
|
||||
log_error("\tVector size %d failed: 0x%llx is not properly aligned.\n", 1 << i, results_data[i]);
|
||||
log_error("\tVector size %d failed: 0x%" PRIx64
|
||||
" is not properly aligned.\n",
|
||||
1 << i, results_data[i]);
|
||||
} else {
|
||||
if (DEBUG) log_info("\tVector size %d passed: 0x%llx is properly aligned.\n", 1 << i, results_data[i]);
|
||||
if (DEBUG)
|
||||
log_info("\tVector size %d passed: 0x%" PRIx64
|
||||
" is properly aligned.\n",
|
||||
1 << i, results_data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -468,9 +495,14 @@ static int test_kernel_memory_alignment(cl_device_id device, cl_context context,
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if ((results_data_no_long[i] & alignments[i]) != 0) {
|
||||
total_errors++;
|
||||
log_error("\tVector size %d failed: 0x%llx is not properly aligned.\n", 1 << i, results_data_no_long[i]);
|
||||
log_error("\tVector size %d failed: 0x%x is not "
|
||||
"properly aligned.\n",
|
||||
1 << i, results_data_no_long[i]);
|
||||
} else {
|
||||
if (DEBUG) log_info("\tVector size %d passed: 0x%llx is properly aligned.\n", 1 << i, results_data_no_long[i]);
|
||||
if (DEBUG)
|
||||
log_info("\tVector size %d passed: 0x%x is "
|
||||
"properly aligned.\n",
|
||||
1 << i, results_data_no_long[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
//
|
||||
#include "testBase.h"
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
#define TEST_VALUE_POSITIVE( string_name, name, value ) \
|
||||
{ \
|
||||
if (name < value) { \
|
||||
@@ -528,7 +530,14 @@ const char *kernel_constant_double_limits[] = {
|
||||
};
|
||||
|
||||
#define TEST_FLOAT_ASSERTION( a, msg, f ) if( !( a ) ) { log_error( "ERROR: Float constant failed requirement: %s (bitwise value is 0x%8.8x)\n", msg, *( (uint32_t *)&f ) ); return -1; }
|
||||
#define TEST_DOUBLE_ASSERTION( a, msg, f ) if( !( a ) ) { log_error( "ERROR: Double constant failed requirement: %s (bitwise value is 0x%16.16llx)\n", msg, *( (uint64_t *)&f ) ); return -1; }
|
||||
#define TEST_DOUBLE_ASSERTION(a, msg, f) \
|
||||
if (!(a)) \
|
||||
{ \
|
||||
log_error("ERROR: Double constant failed requirement: %s (bitwise " \
|
||||
"value is 0x%16.16" PRIx64 ")\n", \
|
||||
msg, *((uint64_t *)&f)); \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
REGISTER_TEST(kernel_limit_constants)
|
||||
{
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
#include "testBase.h"
|
||||
|
||||
cl_int get_type_size( cl_context context, cl_command_queue queue, const char *type, cl_ulong *size, cl_device_id device )
|
||||
@@ -161,12 +163,16 @@ REGISTER_TEST(sizeof)
|
||||
return err;
|
||||
if( test != scalar_table[i].size )
|
||||
{
|
||||
log_error( "\nFAILED: Type %s has size %lld, but expected size %lld!\n", scalar_table[i].name, test, scalar_table[i].size );
|
||||
log_error("\nFAILED: Type %s has size %" PRId64
|
||||
", but expected size %" PRId64 "!\n",
|
||||
scalar_table[i].name, test, scalar_table[i].size);
|
||||
return -1;
|
||||
}
|
||||
if( test != scalar_table[i].cl_size )
|
||||
{
|
||||
log_error( "\nFAILED: Type %s has size %lld, but cl_ size is %lld!\n", scalar_table[i].name, test, scalar_table[i].cl_size );
|
||||
log_error("\nFAILED: Type %s has size %" PRId64
|
||||
", but cl_ size is %" PRId64 "!\n",
|
||||
scalar_table[i].name, test, scalar_table[i].cl_size);
|
||||
return -2;
|
||||
}
|
||||
log_info( "%16s", scalar_table[i].name );
|
||||
@@ -196,16 +202,16 @@ REGISTER_TEST(sizeof)
|
||||
return err;
|
||||
if( test != j * vector_table[i].size )
|
||||
{
|
||||
log_error(
|
||||
"\nFAILED: Type %s has size %lld, but expected size %zu!\n",
|
||||
name, test, j * vector_table[i].size);
|
||||
log_error("\nFAILED: Type %s has size %" PRId64
|
||||
", but expected size %" PRIu64 "!\n",
|
||||
name, test, j * vector_table[i].size);
|
||||
return -1;
|
||||
}
|
||||
if( test != j * vector_table[i].cl_size )
|
||||
{
|
||||
log_error(
|
||||
"\nFAILED: Type %s has size %lld, but cl_ size is %zu!\n",
|
||||
name, test, j * vector_table[i].cl_size);
|
||||
log_error("\nFAILED: Type %s has size %" PRId64
|
||||
", but cl_ size is %" PRIu64 "!\n",
|
||||
name, test, j * vector_table[i].cl_size);
|
||||
return -2;
|
||||
}
|
||||
log_info( "%16s", name );
|
||||
@@ -222,7 +228,9 @@ REGISTER_TEST(sizeof)
|
||||
return err;
|
||||
if( test != ptr_size )
|
||||
{
|
||||
log_error( "\nFAILED: Type %s has size %lld, but expected size %u!\n", ptr_table[i], test, ptr_size );
|
||||
log_error("\nFAILED: Type %s has size %" PRId64
|
||||
", but expected size %u!\n",
|
||||
ptr_table[i], test, ptr_size);
|
||||
return -1;
|
||||
}
|
||||
log_info( "%16s", ptr_table[i] );
|
||||
@@ -235,12 +243,16 @@ REGISTER_TEST(sizeof)
|
||||
return err;
|
||||
if( test < ptr_size )
|
||||
{
|
||||
log_error( "\nFAILED: intptr_t has size %lld, but must be at least %u!\n", test, ptr_size );
|
||||
log_error("\nFAILED: intptr_t has size %" PRId64
|
||||
", but must be at least %u!\n",
|
||||
test, ptr_size);
|
||||
return -1;
|
||||
}
|
||||
if( ! IsPowerOfTwo( test ) )
|
||||
{
|
||||
log_error( "\nFAILED: sizeof(intptr_t) is %lld, but must be a power of two!\n", test );
|
||||
log_error("\nFAILED: sizeof(intptr_t) is %" PRId64
|
||||
", but must be a power of two!\n",
|
||||
test);
|
||||
return -2;
|
||||
}
|
||||
log_info( "%16s", "intptr_t" );
|
||||
@@ -252,12 +264,16 @@ REGISTER_TEST(sizeof)
|
||||
return err;
|
||||
if( test < ptr_size )
|
||||
{
|
||||
log_error( "\nFAILED: uintptr_t has size %lld, but must be at least %u!\n", test, ptr_size );
|
||||
log_error("\nFAILED: uintptr_t has size %" PRId64
|
||||
", but must be at least %u!\n",
|
||||
test, ptr_size);
|
||||
return -1;
|
||||
}
|
||||
if( ! IsPowerOfTwo( test ) )
|
||||
{
|
||||
log_error( "\nFAILED: sizeof(uintptr_t) is %lld, but must be a power of two!\n", test );
|
||||
log_error("\nFAILED: sizeof(uintptr_t) is %" PRId64
|
||||
", but must be a power of two!\n",
|
||||
test);
|
||||
return -2;
|
||||
}
|
||||
log_info( "%16s\n", "uintptr_t" );
|
||||
@@ -293,7 +309,9 @@ REGISTER_TEST(sizeof)
|
||||
return err;
|
||||
if( ! IsPowerOfTwo( test ) )
|
||||
{
|
||||
log_error( "\nFAILED: Type %s has size %lld, which is not a power of two (section 6.1.5)!\n", other_types[i], test );
|
||||
log_error("\nFAILED: Type %s has size %" PRId64
|
||||
", which is not a power of two (section 6.1.5)!\n",
|
||||
other_types[i], test);
|
||||
return -1;
|
||||
}
|
||||
log_info( "%16s", other_types[i] );
|
||||
@@ -311,7 +329,8 @@ REGISTER_TEST(sizeof)
|
||||
return err;
|
||||
if( test != 8 )
|
||||
{
|
||||
log_error( "\nFAILED: double has size %lld, but must be 8!\n", test );
|
||||
log_error("\nFAILED: double has size %" PRId64 ", but must be 8!\n",
|
||||
test);
|
||||
return -1;
|
||||
}
|
||||
log_info( "%16s", "double" );
|
||||
@@ -328,7 +347,8 @@ REGISTER_TEST(sizeof)
|
||||
return err;
|
||||
if( test != 8*j )
|
||||
{
|
||||
log_error("\nFAILED: %s has size %lld, but must be %zu!\n",
|
||||
log_error("\nFAILED: %s has size %" PRId64
|
||||
", but must be %zu!\n",
|
||||
name, test, 8 * j);
|
||||
return -1;
|
||||
}
|
||||
@@ -347,7 +367,8 @@ REGISTER_TEST(sizeof)
|
||||
return err;
|
||||
if( test != 2 )
|
||||
{
|
||||
log_error( "\nFAILED: half has size %lld, but must be 2!\n", test );
|
||||
log_error("\nFAILED: half has size %" PRId64 ", but must be 2!\n",
|
||||
test);
|
||||
return -1;
|
||||
}
|
||||
log_info( "%16s", "half" );
|
||||
@@ -364,7 +385,8 @@ REGISTER_TEST(sizeof)
|
||||
return err;
|
||||
if( test != 2*j )
|
||||
{
|
||||
log_error("\nFAILED: %s has size %lld, but must be %zu!\n",
|
||||
log_error("\nFAILED: %s has size %" PRId64
|
||||
", but must be %zu!\n",
|
||||
name, test, 2 * j);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -605,7 +605,7 @@ template <typename T, size_t N>
|
||||
static int test_vectype(const char* type_name, cl_device_id device,
|
||||
cl_context context, cl_command_queue queue)
|
||||
{
|
||||
log_info(" testing type %s%d\n", type_name, N);
|
||||
log_info(" testing type %s%zu\n", type_name, N);
|
||||
|
||||
cl_int error = CL_SUCCESS;
|
||||
int result = TEST_PASS;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
//
|
||||
#include "harness/compat.h"
|
||||
|
||||
#include <memory>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -36,210 +37,246 @@ static int verify_copy_buffer(int *inptr, int *outptr, int n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
using alignedOwningPtr = std::unique_ptr<cl_int[], decltype(&align_free)>;
|
||||
|
||||
static int test_copy( cl_command_queue queue, cl_context context, int num_elements, MTdata d )
|
||||
{
|
||||
cl_mem buffers[2];
|
||||
cl_int *int_input_ptr, *int_output_ptr;
|
||||
cl_int err;
|
||||
int i;
|
||||
int src_flag_id, dst_flag_id;
|
||||
int errors = 0;
|
||||
clMemWrapper buffers[2];
|
||||
cl_int err = CL_SUCCESS;
|
||||
|
||||
size_t min_alignment = get_min_alignment(context);
|
||||
|
||||
int_input_ptr = (cl_int*) align_malloc(sizeof(cl_int) * num_elements, min_alignment);
|
||||
int_output_ptr = (cl_int*)align_malloc(sizeof(cl_int) * num_elements, min_alignment);
|
||||
alignedOwningPtr invalid_ptr{
|
||||
(cl_int *)align_malloc(sizeof(cl_int) * num_elements, min_alignment),
|
||||
align_free
|
||||
};
|
||||
if (!invalid_ptr)
|
||||
{
|
||||
log_error(" unable to allocate %zu bytes of memory\n",
|
||||
sizeof(cl_int) * num_elements);
|
||||
return TEST_FAIL;
|
||||
}
|
||||
alignedOwningPtr out_ptr{ (cl_int *)align_malloc(
|
||||
sizeof(cl_int) * num_elements, min_alignment),
|
||||
align_free };
|
||||
if (!out_ptr)
|
||||
{
|
||||
log_error(" unable to allocate %zu bytes of memory\n",
|
||||
sizeof(cl_int) * num_elements);
|
||||
return TEST_FAIL;
|
||||
}
|
||||
alignedOwningPtr reference_ptr{
|
||||
(cl_int *)align_malloc(sizeof(cl_int) * num_elements, min_alignment),
|
||||
align_free
|
||||
};
|
||||
if (!reference_ptr)
|
||||
{
|
||||
log_error(" unable to allocate %zu bytes of memory\n",
|
||||
sizeof(cl_int) * num_elements);
|
||||
return TEST_FAIL;
|
||||
}
|
||||
|
||||
for (src_flag_id=0; src_flag_id < NUM_FLAGS; src_flag_id++) {
|
||||
for (dst_flag_id=0; dst_flag_id < NUM_FLAGS; dst_flag_id++) {
|
||||
for (int src_flag_id = 0; src_flag_id < NUM_FLAGS; src_flag_id++)
|
||||
{
|
||||
for (int dst_flag_id = 0; dst_flag_id < NUM_FLAGS; dst_flag_id++)
|
||||
{
|
||||
log_info("Testing with cl_mem_flags src: %s dst: %s\n", flag_set_names[src_flag_id], flag_set_names[dst_flag_id]);
|
||||
|
||||
for (i=0; i<num_elements; i++){
|
||||
int_input_ptr[i] = (int)genrand_int32( d );
|
||||
int_output_ptr[i] = 0xdeaddead; // seed with incorrect data
|
||||
for (int i = 0; i < num_elements; i++)
|
||||
{
|
||||
invalid_ptr[i] = static_cast<int>(0xdeaddead);
|
||||
out_ptr[i] = static_cast<int>(0xdeadbeef);
|
||||
reference_ptr[i] = (int)genrand_int32(d);
|
||||
}
|
||||
|
||||
|
||||
if ((flag_set[src_flag_id] & CL_MEM_USE_HOST_PTR) || (flag_set[src_flag_id] & CL_MEM_COPY_HOST_PTR))
|
||||
buffers[0] = clCreateBuffer(context, flag_set[src_flag_id], sizeof(cl_int) * num_elements, int_input_ptr, &err);
|
||||
buffers[0] = clCreateBuffer(context, flag_set[src_flag_id],
|
||||
sizeof(cl_int) * num_elements,
|
||||
reference_ptr.get(), &err);
|
||||
else
|
||||
buffers[0] = clCreateBuffer(context, flag_set[src_flag_id], sizeof(cl_int) * num_elements, NULL, &err);
|
||||
buffers[0] = clCreateBuffer(context, flag_set[src_flag_id],
|
||||
sizeof(cl_int) * num_elements,
|
||||
nullptr, &err);
|
||||
if ( err != CL_SUCCESS ){
|
||||
print_error(err, " clCreateBuffer failed\n" );
|
||||
align_free( (void *)int_input_ptr );
|
||||
align_free( (void *)int_output_ptr );
|
||||
return -1;
|
||||
print_error(err, "clCreateBuffer failed\n");
|
||||
return TEST_FAIL;
|
||||
}
|
||||
|
||||
if ((flag_set[dst_flag_id] & CL_MEM_USE_HOST_PTR) || (flag_set[dst_flag_id] & CL_MEM_COPY_HOST_PTR))
|
||||
buffers[1] = clCreateBuffer(context, flag_set[dst_flag_id], sizeof(cl_int) * num_elements, int_output_ptr, &err);
|
||||
buffers[1] = clCreateBuffer(context, flag_set[dst_flag_id],
|
||||
sizeof(cl_int) * num_elements,
|
||||
invalid_ptr.get(), &err);
|
||||
else
|
||||
buffers[1] = clCreateBuffer(context, flag_set[dst_flag_id], sizeof(cl_int) * num_elements, NULL, &err);
|
||||
buffers[1] = clCreateBuffer(context, flag_set[dst_flag_id],
|
||||
sizeof(cl_int) * num_elements,
|
||||
nullptr, &err);
|
||||
if ( err != CL_SUCCESS ){
|
||||
print_error(err, " clCreateBuffer failed\n" );
|
||||
clReleaseMemObject( buffers[0] );
|
||||
align_free( (void *)int_input_ptr );
|
||||
align_free( (void *)int_output_ptr );
|
||||
return -1;
|
||||
print_error(err, "clCreateBuffer failed\n");
|
||||
return TEST_FAIL;
|
||||
}
|
||||
|
||||
if (!(flag_set[src_flag_id] & CL_MEM_USE_HOST_PTR) && !(flag_set[src_flag_id] & CL_MEM_COPY_HOST_PTR)) {
|
||||
err = clEnqueueWriteBuffer(queue, buffers[0], CL_TRUE, 0, sizeof(cl_int)*num_elements, (void *)int_input_ptr, 0, NULL, NULL);
|
||||
err = clEnqueueWriteBuffer(queue, buffers[0], CL_TRUE, 0,
|
||||
sizeof(cl_int) * num_elements,
|
||||
reference_ptr.get(), 0, nullptr,
|
||||
nullptr);
|
||||
if ( err != CL_SUCCESS ){
|
||||
print_error( err, "clEnqueueWriteBuffer failed" );
|
||||
clReleaseMemObject( buffers[0] );
|
||||
clReleaseMemObject( buffers[1] );
|
||||
align_free( (void *)int_output_ptr );
|
||||
align_free( (void *)int_input_ptr );
|
||||
return -1;
|
||||
print_error(err, "clEnqueueWriteBuffer failed\n");
|
||||
return TEST_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
err = clEnqueueCopyBuffer(queue, buffers[0], buffers[1], 0, 0, sizeof(cl_int)*num_elements, 0, NULL, NULL);
|
||||
err = clEnqueueCopyBuffer(queue, buffers[0], buffers[1], 0, 0,
|
||||
sizeof(cl_int) * num_elements, 0, nullptr,
|
||||
nullptr);
|
||||
if ( err != CL_SUCCESS ){
|
||||
print_error( err, "clCopyArray failed" );
|
||||
clReleaseMemObject( buffers[0] );
|
||||
clReleaseMemObject( buffers[1] );
|
||||
align_free( (void *)int_output_ptr );
|
||||
align_free( (void *)int_input_ptr );
|
||||
return -1;
|
||||
print_error(err, "clCopyArray failed\n");
|
||||
return TEST_FAIL;
|
||||
}
|
||||
|
||||
err = clEnqueueReadBuffer( queue, buffers[1], true, 0, sizeof(int)*num_elements, (void *)int_output_ptr, 0, NULL, NULL );
|
||||
err = clEnqueueReadBuffer(queue, buffers[1], true, 0,
|
||||
sizeof(int) * num_elements, out_ptr.get(),
|
||||
0, nullptr, nullptr);
|
||||
if ( err != CL_SUCCESS ){
|
||||
print_error( err, "clEnqueueReadBuffer failed" );
|
||||
clReleaseMemObject( buffers[0] );
|
||||
clReleaseMemObject( buffers[1] );
|
||||
align_free( (void *)int_output_ptr );
|
||||
align_free( (void *)int_input_ptr );
|
||||
return -1;
|
||||
print_error(err, "clEnqueueReadBuffer failed\n");
|
||||
return TEST_FAIL;
|
||||
}
|
||||
|
||||
if ( verify_copy_buffer(int_input_ptr, int_output_ptr, num_elements) ){
|
||||
if (verify_copy_buffer(reference_ptr.get(), out_ptr.get(),
|
||||
num_elements))
|
||||
{
|
||||
log_error( " test failed\n" );
|
||||
errors++;
|
||||
return TEST_FAIL;
|
||||
}
|
||||
else{
|
||||
log_info( " test passed\n" );
|
||||
}
|
||||
// cleanup
|
||||
clReleaseMemObject( buffers[0] );
|
||||
clReleaseMemObject( buffers[1] );
|
||||
} // dst flags
|
||||
} // src flags
|
||||
// cleanup
|
||||
align_free( (void *)int_output_ptr );
|
||||
align_free( (void *)int_input_ptr );
|
||||
} // src flags
|
||||
|
||||
return errors;
|
||||
return TEST_PASS;
|
||||
|
||||
} // end test_copy()
|
||||
|
||||
|
||||
static int testPartialCopy( cl_command_queue queue, cl_context context, int num_elements, cl_uint srcStart, cl_uint dstStart, int size, MTdata d )
|
||||
{
|
||||
cl_mem buffers[2];
|
||||
int *inptr, *outptr;
|
||||
cl_int err;
|
||||
int i;
|
||||
int src_flag_id, dst_flag_id;
|
||||
int errors = 0;
|
||||
clMemWrapper buffers[2];
|
||||
cl_int err = CL_SUCCESS;
|
||||
|
||||
size_t min_alignment = get_min_alignment(context);
|
||||
|
||||
inptr = (int *)align_malloc( sizeof(int) * num_elements, min_alignment);
|
||||
if ( ! inptr ){
|
||||
log_error( " unable to allocate %d bytes of memory\n", (int)sizeof(int) * num_elements );
|
||||
return -1;
|
||||
alignedOwningPtr invalid_ptr{
|
||||
(cl_int *)align_malloc(sizeof(cl_int) * num_elements, min_alignment),
|
||||
align_free
|
||||
};
|
||||
if (!invalid_ptr)
|
||||
{
|
||||
log_error(" unable to allocate %zu bytes of memory\n",
|
||||
sizeof(cl_int) * num_elements);
|
||||
return TEST_FAIL;
|
||||
}
|
||||
outptr = (int *)align_malloc( sizeof(int) * num_elements, min_alignment);
|
||||
if ( ! outptr ){
|
||||
log_error( " unable to allocate %d bytes of memory\n", (int)sizeof(int) * num_elements );
|
||||
align_free( (void *)inptr );
|
||||
return -1;
|
||||
alignedOwningPtr out_ptr{ (cl_int *)align_malloc(
|
||||
sizeof(cl_int) * num_elements, min_alignment),
|
||||
align_free };
|
||||
if (!out_ptr)
|
||||
{
|
||||
log_error(" unable to allocate %zu bytes of memory\n",
|
||||
sizeof(cl_int) * num_elements);
|
||||
return TEST_FAIL;
|
||||
}
|
||||
alignedOwningPtr reference_ptr{
|
||||
(cl_int *)align_malloc(sizeof(cl_int) * num_elements, min_alignment),
|
||||
align_free
|
||||
};
|
||||
if (!reference_ptr)
|
||||
{
|
||||
log_error(" unable to allocate %zu bytes of memory\n",
|
||||
sizeof(cl_int) * num_elements);
|
||||
return TEST_FAIL;
|
||||
}
|
||||
|
||||
for (src_flag_id=0; src_flag_id < NUM_FLAGS; src_flag_id++) {
|
||||
for (dst_flag_id=0; dst_flag_id < NUM_FLAGS; dst_flag_id++) {
|
||||
for (int src_flag_id = 0; src_flag_id < NUM_FLAGS; src_flag_id++)
|
||||
{
|
||||
for (int dst_flag_id = 0; dst_flag_id < NUM_FLAGS; dst_flag_id++)
|
||||
{
|
||||
log_info("Testing with cl_mem_flags src: %s dst: %s\n", flag_set_names[src_flag_id], flag_set_names[dst_flag_id]);
|
||||
|
||||
for (i=0; i<num_elements; i++){
|
||||
inptr[i] = (int)genrand_int32( d );
|
||||
outptr[i] = (int)0xdeaddead; // seed with incorrect data
|
||||
for (int i = 0; i < num_elements; i++)
|
||||
{
|
||||
invalid_ptr[i] = static_cast<int>(0xdeaddead);
|
||||
out_ptr[i] = static_cast<int>(0xdeadbeef);
|
||||
reference_ptr[i] = (int)genrand_int32(d);
|
||||
}
|
||||
|
||||
if ((flag_set[src_flag_id] & CL_MEM_USE_HOST_PTR) || (flag_set[src_flag_id] & CL_MEM_COPY_HOST_PTR))
|
||||
buffers[0] = clCreateBuffer(context, flag_set[src_flag_id], sizeof(cl_int) * num_elements, inptr, &err);
|
||||
buffers[0] = clCreateBuffer(context, flag_set[src_flag_id],
|
||||
sizeof(cl_int) * num_elements,
|
||||
reference_ptr.get(), &err);
|
||||
else
|
||||
buffers[0] = clCreateBuffer(context, flag_set[src_flag_id], sizeof(cl_int) * num_elements, NULL, &err);
|
||||
buffers[0] = clCreateBuffer(context, flag_set[src_flag_id],
|
||||
sizeof(cl_int) * num_elements,
|
||||
nullptr, &err);
|
||||
if ( err != CL_SUCCESS ){
|
||||
print_error(err, " clCreateBuffer failed\n" )
|
||||
align_free( (void *)outptr );
|
||||
align_free( (void *)inptr );
|
||||
return -1;
|
||||
print_error(err, "clCreateBuffer failed\n");
|
||||
return TEST_FAIL;
|
||||
}
|
||||
|
||||
if ((flag_set[dst_flag_id] & CL_MEM_USE_HOST_PTR) || (flag_set[dst_flag_id] & CL_MEM_COPY_HOST_PTR))
|
||||
buffers[1] = clCreateBuffer(context, flag_set[dst_flag_id], sizeof(cl_int) * num_elements, outptr, &err);
|
||||
buffers[1] = clCreateBuffer(context, flag_set[dst_flag_id],
|
||||
sizeof(cl_int) * num_elements,
|
||||
invalid_ptr.get(), &err);
|
||||
else
|
||||
buffers[1] = clCreateBuffer(context, flag_set[dst_flag_id], sizeof(cl_int) * num_elements, NULL, &err);
|
||||
buffers[1] = clCreateBuffer(context, flag_set[dst_flag_id],
|
||||
sizeof(cl_int) * num_elements,
|
||||
nullptr, &err);
|
||||
if ( err != CL_SUCCESS ){
|
||||
print_error(err, " clCreateBuffer failed\n" );
|
||||
clReleaseMemObject( buffers[0] );
|
||||
align_free( (void *)outptr );
|
||||
align_free( (void *)inptr );
|
||||
return -1;
|
||||
print_error(err, "clCreateBuffer failed\n");
|
||||
return TEST_FAIL;
|
||||
}
|
||||
|
||||
if (!(flag_set[src_flag_id] & CL_MEM_USE_HOST_PTR) && !(flag_set[src_flag_id] & CL_MEM_COPY_HOST_PTR)){
|
||||
err = clEnqueueWriteBuffer(queue, buffers[0], CL_TRUE, 0, sizeof(cl_int)*num_elements, (void *)inptr, 0, NULL, NULL);
|
||||
err = clEnqueueWriteBuffer(queue, buffers[0], CL_TRUE, 0,
|
||||
sizeof(cl_int) * num_elements,
|
||||
reference_ptr.get(), 0, nullptr,
|
||||
nullptr);
|
||||
if ( err != CL_SUCCESS ){
|
||||
print_error( err, "clEnqueueWriteBuffer failed" );
|
||||
clReleaseMemObject( buffers[1] );
|
||||
clReleaseMemObject( buffers[0] );
|
||||
align_free( (void *)outptr );
|
||||
align_free( (void *)inptr );
|
||||
return -1;
|
||||
print_error(err, "clEnqueueWriteBuffer failed\n");
|
||||
return TEST_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
err = clEnqueueCopyBuffer(queue, buffers[0], buffers[1], srcStart*sizeof(cl_int), dstStart*sizeof(cl_int), sizeof(cl_int)*size, 0, NULL, NULL);
|
||||
err = clEnqueueCopyBuffer(
|
||||
queue, buffers[0], buffers[1], srcStart * sizeof(cl_int),
|
||||
dstStart * sizeof(cl_int), sizeof(cl_int) * size, 0, nullptr,
|
||||
nullptr);
|
||||
if ( err != CL_SUCCESS){
|
||||
print_error( err, "clEnqueueCopyBuffer failed" );
|
||||
clReleaseMemObject( buffers[1] );
|
||||
clReleaseMemObject( buffers[0] );
|
||||
align_free( (void *)outptr );
|
||||
align_free( (void *)inptr );
|
||||
return -1;
|
||||
print_error(err, "clEnqueueCopyBuffer failed\n");
|
||||
return TEST_FAIL;
|
||||
}
|
||||
|
||||
err = clEnqueueReadBuffer( queue, buffers[1], true, 0, sizeof(int)*num_elements, (void *)outptr, 0, NULL, NULL );
|
||||
err = clEnqueueReadBuffer(queue, buffers[1], true, 0,
|
||||
sizeof(int) * num_elements, out_ptr.get(),
|
||||
0, nullptr, nullptr);
|
||||
if ( err != CL_SUCCESS){
|
||||
print_error( err, "clEnqueueReadBuffer failed" );
|
||||
clReleaseMemObject( buffers[1] );
|
||||
clReleaseMemObject( buffers[0] );
|
||||
align_free( (void *)outptr );
|
||||
align_free( (void *)inptr );
|
||||
return -1;
|
||||
print_error(err, "clEnqueueReadBuffer failed\n");
|
||||
return TEST_FAIL;
|
||||
}
|
||||
|
||||
if ( verify_copy_buffer(inptr + srcStart, outptr + dstStart, size) ){
|
||||
if (verify_copy_buffer(reference_ptr.get() + srcStart,
|
||||
out_ptr.get() + dstStart, size))
|
||||
{
|
||||
log_error("buffer_COPY test failed\n");
|
||||
errors++;
|
||||
return TEST_FAIL;
|
||||
}
|
||||
else{
|
||||
log_info("buffer_COPY test passed\n");
|
||||
}
|
||||
// cleanup
|
||||
clReleaseMemObject( buffers[1] );
|
||||
clReleaseMemObject( buffers[0] );
|
||||
} // dst mem flags
|
||||
} // src mem flags
|
||||
// cleanup
|
||||
align_free( (void *)outptr );
|
||||
align_free( (void *)inptr );
|
||||
|
||||
return errors;
|
||||
return TEST_PASS;
|
||||
|
||||
} // end testPartialCopy()
|
||||
|
||||
@@ -252,15 +289,19 @@ REGISTER_TEST(buffer_copy)
|
||||
|
||||
// test the preset size
|
||||
log_info( "set size: %d: ", num_elements );
|
||||
if (test_copy( queue, context, num_elements, d ))
|
||||
if (test_copy(queue, context, num_elements, d) != TEST_PASS)
|
||||
{
|
||||
err++;
|
||||
}
|
||||
|
||||
// now test random sizes
|
||||
for ( i = 0; i < 8; i++ ){
|
||||
size = (int)get_random_float(2.f,131072.f, d);
|
||||
log_info( "random size: %d: ", size );
|
||||
if (test_copy( queue, context, size, d ))
|
||||
if (test_copy(queue, context, size, d) != TEST_PASS)
|
||||
{
|
||||
err++;
|
||||
}
|
||||
}
|
||||
|
||||
free_mtdata(d);
|
||||
@@ -283,8 +324,12 @@ REGISTER_TEST(buffer_partial_copy)
|
||||
size = (int)get_random_float( 8.f, (float)(num_elements - srcStart), d );
|
||||
dstStart = (cl_uint)get_random_float( 0.f, (float)(num_elements - size), d );
|
||||
log_info( "random partial copy from %d to %d, size: %d: ", (int)srcStart, (int)dstStart, size );
|
||||
if (testPartialCopy( queue, context, num_elements, srcStart, dstStart, size, d ))
|
||||
if (testPartialCopy(queue, context, num_elements, srcStart, dstStart,
|
||||
size, d)
|
||||
!= TEST_PASS)
|
||||
{
|
||||
err++;
|
||||
}
|
||||
}
|
||||
|
||||
free_mtdata(d);
|
||||
|
||||
@@ -58,30 +58,28 @@ cl_uint AtomicTypeInfo::Size(cl_device_id device)
|
||||
{
|
||||
switch(_type)
|
||||
{
|
||||
case TYPE_ATOMIC_INT:
|
||||
case TYPE_ATOMIC_UINT:
|
||||
case TYPE_ATOMIC_FLOAT:
|
||||
case TYPE_ATOMIC_FLAG:
|
||||
return sizeof(cl_int);
|
||||
case TYPE_ATOMIC_LONG:
|
||||
case TYPE_ATOMIC_ULONG:
|
||||
case TYPE_ATOMIC_DOUBLE:
|
||||
return sizeof(cl_long);
|
||||
case TYPE_ATOMIC_INTPTR_T:
|
||||
case TYPE_ATOMIC_UINTPTR_T:
|
||||
case TYPE_ATOMIC_SIZE_T:
|
||||
case TYPE_ATOMIC_PTRDIFF_T:
|
||||
{
|
||||
int error;
|
||||
cl_uint addressBits = 0;
|
||||
case TYPE_ATOMIC_HALF: return sizeof(cl_half);
|
||||
case TYPE_ATOMIC_INT:
|
||||
case TYPE_ATOMIC_UINT:
|
||||
case TYPE_ATOMIC_FLOAT:
|
||||
case TYPE_ATOMIC_FLAG: return sizeof(cl_int);
|
||||
case TYPE_ATOMIC_LONG:
|
||||
case TYPE_ATOMIC_ULONG:
|
||||
case TYPE_ATOMIC_DOUBLE: return sizeof(cl_long);
|
||||
case TYPE_ATOMIC_INTPTR_T:
|
||||
case TYPE_ATOMIC_UINTPTR_T:
|
||||
case TYPE_ATOMIC_SIZE_T:
|
||||
case TYPE_ATOMIC_PTRDIFF_T: {
|
||||
int error;
|
||||
cl_uint addressBits = 0;
|
||||
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_ADDRESS_BITS, sizeof(addressBits), &addressBits, 0);
|
||||
test_error_ret(error, "clGetDeviceInfo", 0);
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_ADDRESS_BITS,
|
||||
sizeof(addressBits), &addressBits, 0);
|
||||
test_error_ret(error, "clGetDeviceInfo", 0);
|
||||
|
||||
return addressBits/8;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
return addressBits / 8;
|
||||
}
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +91,7 @@ const char *AtomicTypeInfo::AtomicTypeName()
|
||||
return "atomic_int";
|
||||
case TYPE_ATOMIC_UINT:
|
||||
return "atomic_uint";
|
||||
case TYPE_ATOMIC_HALF: return "atomic_half";
|
||||
case TYPE_ATOMIC_FLOAT:
|
||||
return "atomic_float";
|
||||
case TYPE_ATOMIC_FLAG:
|
||||
@@ -124,6 +123,7 @@ const char *AtomicTypeInfo::RegularTypeName()
|
||||
return "int";
|
||||
case TYPE_ATOMIC_UINT:
|
||||
return "uint";
|
||||
case TYPE_ATOMIC_HALF: return "half";
|
||||
case TYPE_ATOMIC_FLOAT:
|
||||
return "float";
|
||||
case TYPE_ATOMIC_FLAG:
|
||||
@@ -163,29 +163,30 @@ int AtomicTypeInfo::IsSupported(cl_device_id device)
|
||||
{
|
||||
switch(_type)
|
||||
{
|
||||
case TYPE_ATOMIC_INT:
|
||||
case TYPE_ATOMIC_UINT:
|
||||
case TYPE_ATOMIC_FLOAT:
|
||||
case TYPE_ATOMIC_FLAG:
|
||||
return 1;
|
||||
case TYPE_ATOMIC_LONG:
|
||||
case TYPE_ATOMIC_ULONG:
|
||||
return is_extension_available(device, "cl_khr_int64_base_atomics") &&
|
||||
is_extension_available(device, "cl_khr_int64_extended_atomics");
|
||||
case TYPE_ATOMIC_DOUBLE:
|
||||
return is_extension_available(device, "cl_khr_int64_base_atomics") &&
|
||||
is_extension_available(device, "cl_khr_int64_extended_atomics") &&
|
||||
is_extension_available(device, "cl_khr_fp64");
|
||||
case TYPE_ATOMIC_INTPTR_T:
|
||||
case TYPE_ATOMIC_UINTPTR_T:
|
||||
case TYPE_ATOMIC_SIZE_T:
|
||||
case TYPE_ATOMIC_PTRDIFF_T:
|
||||
if(Size(device) == 4)
|
||||
return 1;
|
||||
return is_extension_available(device, "cl_khr_int64_base_atomics") &&
|
||||
is_extension_available(device, "cl_khr_int64_extended_atomics");
|
||||
default:
|
||||
return 0;
|
||||
case TYPE_ATOMIC_HALF:
|
||||
return is_extension_available(device, "cl_khr_fp16");
|
||||
case TYPE_ATOMIC_INT:
|
||||
case TYPE_ATOMIC_UINT:
|
||||
case TYPE_ATOMIC_FLOAT:
|
||||
case TYPE_ATOMIC_FLAG: return 1;
|
||||
case TYPE_ATOMIC_LONG:
|
||||
case TYPE_ATOMIC_ULONG:
|
||||
return is_extension_available(device, "cl_khr_int64_base_atomics")
|
||||
&& is_extension_available(device,
|
||||
"cl_khr_int64_extended_atomics");
|
||||
case TYPE_ATOMIC_DOUBLE:
|
||||
return is_extension_available(device, "cl_khr_int64_base_atomics")
|
||||
&& is_extension_available(device, "cl_khr_int64_extended_atomics")
|
||||
&& is_extension_available(device, "cl_khr_fp64");
|
||||
case TYPE_ATOMIC_INTPTR_T:
|
||||
case TYPE_ATOMIC_UINTPTR_T:
|
||||
case TYPE_ATOMIC_SIZE_T:
|
||||
case TYPE_ATOMIC_PTRDIFF_T:
|
||||
if (Size(device) == 4) return 1;
|
||||
return is_extension_available(device, "cl_khr_int64_base_atomics")
|
||||
&& is_extension_available(device,
|
||||
"cl_khr_int64_extended_atomics");
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
#include "host_atomics.h"
|
||||
|
||||
#include "CL/cl_half.h"
|
||||
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
@@ -38,6 +40,7 @@ enum TExplicitAtomicType
|
||||
TYPE_ATOMIC_UINT,
|
||||
TYPE_ATOMIC_LONG,
|
||||
TYPE_ATOMIC_ULONG,
|
||||
TYPE_ATOMIC_HALF,
|
||||
TYPE_ATOMIC_FLOAT,
|
||||
TYPE_ATOMIC_DOUBLE,
|
||||
TYPE_ATOMIC_INTPTR_T,
|
||||
@@ -71,6 +74,9 @@ extern int
|
||||
gMaxDeviceThreads; // maximum number of threads executed on OCL device
|
||||
extern cl_device_atomic_capabilities gAtomicMemCap,
|
||||
gAtomicFenceCap; // atomic memory and fence capabilities for this device
|
||||
extern cl_half_rounding_mode gHalfRoundingMode;
|
||||
extern bool gFloatAtomicsSupported;
|
||||
extern cl_device_fp_atomic_capabilities_ext gHalfAtomicCaps;
|
||||
|
||||
extern const char *
|
||||
get_memory_order_type_name(TExplicitMemoryOrderType orderType);
|
||||
@@ -240,13 +246,13 @@ public:
|
||||
int error = 0;
|
||||
if (_maxDeviceThreads > 0 && !UseSVM())
|
||||
{
|
||||
LocalMemory(true);
|
||||
SetLocalMemory(true);
|
||||
EXECUTE_TEST(
|
||||
error, ExecuteForEachDeclarationType(deviceID, context, queue));
|
||||
}
|
||||
if (_maxDeviceThreads + MaxHostThreads() > 0)
|
||||
{
|
||||
LocalMemory(false);
|
||||
SetLocalMemory(false);
|
||||
EXECUTE_TEST(
|
||||
error, ExecuteForEachDeclarationType(deviceID, context, queue));
|
||||
}
|
||||
@@ -401,7 +407,7 @@ public:
|
||||
bool UseSVM() { return _useSVM; }
|
||||
void StartValue(HostDataType startValue) { _startValue = startValue; }
|
||||
HostDataType StartValue() { return _startValue; }
|
||||
void LocalMemory(bool local) { _localMemory = local; }
|
||||
void SetLocalMemory(bool local) { _localMemory = local; }
|
||||
bool LocalMemory() { return _localMemory; }
|
||||
void DeclaredInProgram(bool declaredInProgram)
|
||||
{
|
||||
@@ -781,6 +787,8 @@ CBasicTest<HostAtomicType, HostDataType>::PragmaHeader(cl_device_id deviceID)
|
||||
}
|
||||
if (_dataType == TYPE_ATOMIC_DOUBLE)
|
||||
pragma += "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n";
|
||||
if (_dataType == TYPE_ATOMIC_HALF)
|
||||
pragma += "#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n";
|
||||
return pragma;
|
||||
}
|
||||
|
||||
@@ -875,7 +883,14 @@ CBasicTest<HostAtomicType, HostDataType>::ProgramHeader(cl_uint maxNumDestItems)
|
||||
header += std::string("__global volatile ") + aTypeName + " destMemory["
|
||||
+ ss.str() + "] = {\n";
|
||||
ss.str("");
|
||||
ss << _startValue;
|
||||
|
||||
if (CBasicTest<HostAtomicType, HostDataType>::DataType()._type
|
||||
!= TYPE_ATOMIC_HALF)
|
||||
ss << _startValue;
|
||||
else
|
||||
ss << static_cast<HostDataType>(
|
||||
cl_half_to_float(static_cast<cl_half>(_startValue)));
|
||||
|
||||
for (cl_uint i = 0; i < maxNumDestItems; i++)
|
||||
{
|
||||
if (aTypeName == "atomic_flag")
|
||||
|
||||
@@ -41,6 +41,7 @@ enum TExplicitMemoryOrderType
|
||||
#define HOST_ATOMIC_UINT unsigned long
|
||||
#define HOST_ATOMIC_LONG unsigned long long
|
||||
#define HOST_ATOMIC_ULONG unsigned long long
|
||||
#define HOST_ATOMIC_HALF unsigned short
|
||||
#define HOST_ATOMIC_FLOAT float
|
||||
#define HOST_ATOMIC_DOUBLE double
|
||||
#else
|
||||
@@ -48,6 +49,7 @@ enum TExplicitMemoryOrderType
|
||||
#define HOST_ATOMIC_UINT cl_uint
|
||||
#define HOST_ATOMIC_LONG cl_long
|
||||
#define HOST_ATOMIC_ULONG cl_ulong
|
||||
#define HOST_ATOMIC_HALF cl_half
|
||||
#define HOST_ATOMIC_FLOAT cl_float
|
||||
#define HOST_ATOMIC_DOUBLE cl_double
|
||||
#endif
|
||||
@@ -69,6 +71,7 @@ enum TExplicitMemoryOrderType
|
||||
#define HOST_UINT cl_uint
|
||||
#define HOST_LONG cl_long
|
||||
#define HOST_ULONG cl_ulong
|
||||
#define HOST_HALF cl_half
|
||||
#define HOST_FLOAT cl_float
|
||||
#define HOST_DOUBLE cl_double
|
||||
|
||||
@@ -120,9 +123,12 @@ CorrespondingType host_atomic_exchange(volatile AtomicType *a, CorrespondingType
|
||||
TExplicitMemoryOrderType order)
|
||||
{
|
||||
#if defined( _MSC_VER ) || (defined( __INTEL_COMPILER ) && defined(WIN32))
|
||||
return InterlockedExchange(a, c);
|
||||
if (sizeof(CorrespondingType) == 2)
|
||||
return InterlockedExchange16(reinterpret_cast<volatile SHORT *>(a), c);
|
||||
else
|
||||
return InterlockedExchange(reinterpret_cast<volatile LONG *>(a), c);
|
||||
#elif defined(__GNUC__)
|
||||
return __sync_lock_test_and_set(a, c);
|
||||
return __sync_lock_test_and_set(a, c);
|
||||
#else
|
||||
log_info("Host function not implemented: atomic_exchange\n");
|
||||
return 0;
|
||||
@@ -158,7 +164,10 @@ CorrespondingType host_atomic_load(volatile AtomicType *a,
|
||||
TExplicitMemoryOrderType order)
|
||||
{
|
||||
#if defined( _MSC_VER ) || (defined( __INTEL_COMPILER ) && defined(WIN32))
|
||||
return InterlockedExchangeAdd(a, 0);
|
||||
if (sizeof(CorrespondingType) == 2)
|
||||
auto prev = InterlockedOr16(reinterpret_cast<volatile SHORT *>(a), 0);
|
||||
else
|
||||
return InterlockedExchangeAdd(reinterpret_cast<volatile LONG *>(a), 0);
|
||||
#elif defined(__GNUC__)
|
||||
return __sync_add_and_fetch(a, 0);
|
||||
#else
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Copyright (c) 2024 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
|
||||
@@ -14,8 +14,11 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "harness/testHarness.h"
|
||||
#include "harness/deviceInfo.h"
|
||||
#include "harness/kernelHelpers.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "CL/cl_half.h"
|
||||
|
||||
bool gHost = false; // flag for testing native host threads (test verification)
|
||||
bool gOldAPI = false; // flag for testing with old API (OpenCL 1.2) - test verification
|
||||
@@ -28,6 +31,9 @@ int gInternalIterations = 10000; // internal test iterations for atomic operatio
|
||||
int gMaxDeviceThreads = 1024; // maximum number of threads executed on OCL device
|
||||
cl_device_atomic_capabilities gAtomicMemCap,
|
||||
gAtomicFenceCap; // atomic memory and fence capabilities for this device
|
||||
cl_half_rounding_mode gHalfRoundingMode = CL_HALF_RTE;
|
||||
bool gFloatAtomicsSupported = false;
|
||||
cl_device_fp_atomic_capabilities_ext gHalfAtomicCaps = 0;
|
||||
|
||||
test_status InitCL(cl_device_id device) {
|
||||
auto version = get_device_cl_version(device);
|
||||
@@ -123,6 +129,34 @@ test_status InitCL(cl_device_id device) {
|
||||
| CL_DEVICE_ATOMIC_SCOPE_ALL_DEVICES;
|
||||
}
|
||||
|
||||
if (is_extension_available(device, "cl_ext_float_atomics"))
|
||||
{
|
||||
gFloatAtomicsSupported = true;
|
||||
if (is_extension_available(device, "cl_khr_fp16"))
|
||||
{
|
||||
cl_int error = clGetDeviceInfo(
|
||||
device, CL_DEVICE_HALF_FP_ATOMIC_CAPABILITIES_EXT,
|
||||
sizeof(gHalfAtomicCaps), &gHalfAtomicCaps, nullptr);
|
||||
test_error_ret(error, "clGetDeviceInfo failed!", TEST_FAIL);
|
||||
|
||||
const cl_device_fp_config fpConfigHalf =
|
||||
get_default_rounding_mode(device, CL_DEVICE_HALF_FP_CONFIG);
|
||||
if ((fpConfigHalf & CL_FP_ROUND_TO_NEAREST) != 0)
|
||||
{
|
||||
gHalfRoundingMode = CL_HALF_RTE;
|
||||
}
|
||||
else if ((fpConfigHalf & CL_FP_ROUND_TO_ZERO) != 0)
|
||||
{
|
||||
gHalfRoundingMode = CL_HALF_RTZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("Error while acquiring half rounding mode\n");
|
||||
return TEST_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TEST_PASS;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
// Copyright (c) 2024 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.
|
||||
@@ -33,6 +33,7 @@ public:
|
||||
using CBasicTestMemOrderScope<HostAtomicType,
|
||||
HostDataType>::MemoryOrderScopeStr;
|
||||
using CBasicTest<HostAtomicType, HostDataType>::CheckCapabilities;
|
||||
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::LocalMemory;
|
||||
CBasicTestStore(TExplicitAtomicType dataType, bool useSVM)
|
||||
: CBasicTestMemOrderScope<HostAtomicType, HostDataType>(dataType,
|
||||
useSVM)
|
||||
@@ -54,6 +55,21 @@ public:
|
||||
== TEST_SKIPPED_ITSELF)
|
||||
return 0; // skip test - not applicable
|
||||
|
||||
if (CBasicTestMemOrderScope<HostAtomicType, HostDataType>::DataType()
|
||||
._type
|
||||
== TYPE_ATOMIC_HALF)
|
||||
{
|
||||
if (LocalMemory()
|
||||
&& (gHalfAtomicCaps & CL_DEVICE_LOCAL_FP_ATOMIC_LOAD_STORE_EXT)
|
||||
== 0)
|
||||
return 0; // skip test - not applicable
|
||||
|
||||
if (!LocalMemory()
|
||||
&& (gHalfAtomicCaps & CL_DEVICE_GLOBAL_FP_ATOMIC_LOAD_STORE_EXT)
|
||||
== 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CBasicTestMemOrderScope<
|
||||
HostAtomicType, HostDataType>::ExecuteSingleTest(deviceID, context,
|
||||
queue);
|
||||
@@ -75,7 +91,13 @@ public:
|
||||
HostDataType *startRefValues,
|
||||
cl_uint whichDestValue)
|
||||
{
|
||||
expected = (HostDataType)whichDestValue;
|
||||
if (CBasicTestMemOrderScope<HostAtomicType, HostDataType>::DataType()
|
||||
._type
|
||||
!= TYPE_ATOMIC_HALF)
|
||||
expected = (HostDataType)whichDestValue;
|
||||
else
|
||||
expected = cl_half_from_float(static_cast<float>(whichDestValue),
|
||||
gHalfRoundingMode);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -109,6 +131,15 @@ static int test_atomic_store_generic(cl_device_id deviceID, cl_context context,
|
||||
TYPE_ATOMIC_DOUBLE, useSVM);
|
||||
EXECUTE_TEST(error,
|
||||
test_double.Execute(deviceID, context, queue, num_elements));
|
||||
|
||||
if (gFloatAtomicsSupported)
|
||||
{
|
||||
CBasicTestStore<HOST_ATOMIC_HALF, HOST_HALF> test_half(TYPE_ATOMIC_HALF,
|
||||
useSVM);
|
||||
EXECUTE_TEST(error,
|
||||
test_half.Execute(deviceID, context, queue, num_elements));
|
||||
}
|
||||
|
||||
if (AtomicTypeInfo(TYPE_ATOMIC_SIZE_T).Size(deviceID) == 4)
|
||||
{
|
||||
CBasicTestStore<HOST_ATOMIC_INTPTR_T32, HOST_INTPTR_T32> test_intptr_t(
|
||||
@@ -297,6 +328,7 @@ public:
|
||||
HostDataType>::MemoryOrderScopeStr;
|
||||
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::MemoryScopeStr;
|
||||
using CBasicTest<HostAtomicType, HostDataType>::CheckCapabilities;
|
||||
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::LocalMemory;
|
||||
CBasicTestLoad(TExplicitAtomicType dataType, bool useSVM)
|
||||
: CBasicTestMemOrderScope<HostAtomicType, HostDataType>(dataType,
|
||||
useSVM)
|
||||
@@ -318,6 +350,21 @@ public:
|
||||
== TEST_SKIPPED_ITSELF)
|
||||
return 0; // skip test - not applicable
|
||||
|
||||
if (CBasicTestMemOrderScope<HostAtomicType, HostDataType>::DataType()
|
||||
._type
|
||||
== TYPE_ATOMIC_HALF)
|
||||
{
|
||||
if (LocalMemory()
|
||||
&& (gHalfAtomicCaps & CL_DEVICE_LOCAL_FP_ATOMIC_LOAD_STORE_EXT)
|
||||
== 0)
|
||||
return 0; // skip test - not applicable
|
||||
|
||||
if (!LocalMemory()
|
||||
&& (gHalfAtomicCaps & CL_DEVICE_GLOBAL_FP_ATOMIC_LOAD_STORE_EXT)
|
||||
== 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CBasicTestMemOrderScope<
|
||||
HostAtomicType, HostDataType>::ExecuteSingleTest(deviceID, context,
|
||||
queue);
|
||||
@@ -351,7 +398,13 @@ public:
|
||||
HostDataType *startRefValues,
|
||||
cl_uint whichDestValue)
|
||||
{
|
||||
expected = (HostDataType)whichDestValue;
|
||||
if (CBasicTestMemOrderScope<HostAtomicType, HostDataType>::DataType()
|
||||
._type
|
||||
!= TYPE_ATOMIC_HALF)
|
||||
expected = (HostDataType)whichDestValue;
|
||||
else
|
||||
expected = cl_half_from_float(static_cast<float>(whichDestValue),
|
||||
gHalfRoundingMode);
|
||||
return true;
|
||||
}
|
||||
virtual bool VerifyRefs(bool &correct, cl_uint threadCount,
|
||||
@@ -361,11 +414,25 @@ public:
|
||||
correct = true;
|
||||
for (cl_uint i = 0; i < threadCount; i++)
|
||||
{
|
||||
if (refValues[i] != (HostDataType)i)
|
||||
if constexpr (std::is_same<HostDataType, cl_half>::value)
|
||||
{
|
||||
log_error("Invalid value for thread %u\n", (cl_uint)i);
|
||||
correct = false;
|
||||
return true;
|
||||
HostDataType test = cl_half_from_float(static_cast<float>(i),
|
||||
gHalfRoundingMode);
|
||||
if (refValues[i] != test)
|
||||
{
|
||||
log_error("Invalid value for thread %u\n", (cl_uint)i);
|
||||
correct = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (refValues[i] != (HostDataType)i)
|
||||
{
|
||||
log_error("Invalid value for thread %u\n", (cl_uint)i);
|
||||
correct = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -400,6 +467,15 @@ static int test_atomic_load_generic(cl_device_id deviceID, cl_context context,
|
||||
TYPE_ATOMIC_DOUBLE, useSVM);
|
||||
EXECUTE_TEST(error,
|
||||
test_double.Execute(deviceID, context, queue, num_elements));
|
||||
|
||||
if (gFloatAtomicsSupported)
|
||||
{
|
||||
CBasicTestLoad<HOST_ATOMIC_HALF, HOST_HALF> test_half(TYPE_ATOMIC_HALF,
|
||||
useSVM);
|
||||
EXECUTE_TEST(error,
|
||||
test_half.Execute(deviceID, context, queue, num_elements));
|
||||
}
|
||||
|
||||
if (AtomicTypeInfo(TYPE_ATOMIC_SIZE_T).Size(deviceID) == 4)
|
||||
{
|
||||
CBasicTestLoad<HOST_ATOMIC_INTPTR_T32, HOST_INTPTR_T32> test_intptr_t(
|
||||
@@ -469,11 +545,36 @@ public:
|
||||
HostDataType>::MemoryOrderScopeStr;
|
||||
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::Iterations;
|
||||
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::IterationsStr;
|
||||
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::LocalMemory;
|
||||
CBasicTestExchange(TExplicitAtomicType dataType, bool useSVM)
|
||||
: CBasicTestMemOrderScope<HostAtomicType, HostDataType>(dataType,
|
||||
useSVM)
|
||||
{
|
||||
StartValue(123456);
|
||||
if constexpr (std::is_same_v<HostDataType, HOST_ATOMIC_HALF>)
|
||||
StartValue(cl_half_from_float(static_cast<float>(1234),
|
||||
gHalfRoundingMode));
|
||||
else
|
||||
StartValue(123456);
|
||||
}
|
||||
virtual int ExecuteSingleTest(cl_device_id deviceID, cl_context context,
|
||||
cl_command_queue queue)
|
||||
{
|
||||
if constexpr (std::is_same_v<HostDataType, HOST_ATOMIC_HALF>)
|
||||
{
|
||||
if (LocalMemory()
|
||||
&& (gHalfAtomicCaps & CL_DEVICE_LOCAL_FP_ATOMIC_LOAD_STORE_EXT)
|
||||
== 0)
|
||||
return 0; // skip test - not applicable
|
||||
|
||||
if (!LocalMemory()
|
||||
&& (gHalfAtomicCaps & CL_DEVICE_GLOBAL_FP_ATOMIC_LOAD_STORE_EXT)
|
||||
== 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CBasicTestMemOrderScope<
|
||||
HostAtomicType, HostDataType>::ExecuteSingleTest(deviceID, context,
|
||||
queue);
|
||||
}
|
||||
virtual std::string ProgramCore()
|
||||
{
|
||||
@@ -515,17 +616,35 @@ public:
|
||||
/* Any repeated value is treated as an error */
|
||||
std::vector<bool> tidFound(threadCount);
|
||||
bool startValueFound = false;
|
||||
cl_uint i;
|
||||
cl_uint startVal = StartValue();
|
||||
|
||||
for (i = 0; i <= threadCount; i++)
|
||||
if constexpr (std::is_same_v<HostDataType, HOST_ATOMIC_HALF>)
|
||||
startVal = static_cast<cl_uint>(
|
||||
cl_half_to_float(static_cast<cl_half>(StartValue())));
|
||||
|
||||
for (cl_uint i = 0; i <= threadCount; i++)
|
||||
{
|
||||
cl_uint value;
|
||||
cl_uint value = 0;
|
||||
if (i == threadCount)
|
||||
value = (cl_uint)finalValues[0]; // additional value from atomic
|
||||
{
|
||||
if constexpr (!std::is_same_v<HostDataType, HOST_ATOMIC_HALF>)
|
||||
value =
|
||||
(cl_uint)finalValues[0]; // additional value from atomic
|
||||
// variable (last written)
|
||||
else
|
||||
value =
|
||||
cl_half_to_float(static_cast<cl_half>(finalValues[0]));
|
||||
}
|
||||
else
|
||||
value = (cl_uint)refValues[i];
|
||||
if (value == (cl_uint)StartValue())
|
||||
{
|
||||
if constexpr (!std::is_same_v<HostDataType, HOST_ATOMIC_HALF>)
|
||||
value = (cl_uint)refValues[i];
|
||||
else
|
||||
value =
|
||||
cl_half_to_float(static_cast<cl_half>(refValues[i]));
|
||||
}
|
||||
|
||||
if (value == startVal)
|
||||
{
|
||||
// Special initial value
|
||||
if (startValueFound)
|
||||
@@ -590,6 +709,13 @@ static int test_atomic_exchange_generic(cl_device_id deviceID,
|
||||
TYPE_ATOMIC_DOUBLE, useSVM);
|
||||
EXECUTE_TEST(error,
|
||||
test_double.Execute(deviceID, context, queue, num_elements));
|
||||
if (gFloatAtomicsSupported)
|
||||
{
|
||||
CBasicTestExchange<HOST_ATOMIC_HALF, HOST_HALF> test_half(
|
||||
TYPE_ATOMIC_HALF, useSVM);
|
||||
EXECUTE_TEST(error,
|
||||
test_half.Execute(deviceID, context, queue, num_elements));
|
||||
}
|
||||
if (AtomicTypeInfo(TYPE_ATOMIC_SIZE_T).Size(deviceID) == 4)
|
||||
{
|
||||
CBasicTestExchange<HOST_ATOMIC_INTPTR_T32, HOST_INTPTR_T32>
|
||||
|
||||
@@ -6,6 +6,7 @@ set(VULKAN_WRAPPER_SOURCES
|
||||
)
|
||||
|
||||
# needed by Vulkan wrapper to compile
|
||||
set(CMAKE_COMPILE_WARNING_AS_ERROR OFF)
|
||||
add_cxx_flag_if_supported(-Wmisleading-indentation)
|
||||
add_cxx_flag_if_supported(-Wno-narrowing)
|
||||
add_cxx_flag_if_supported(-Wno-format)
|
||||
|
||||
@@ -428,38 +428,68 @@ size_t GetElementNBytes(const cl_image_format *format)
|
||||
return result;
|
||||
}
|
||||
|
||||
cl_int get2DImageDimensions(const VkImageCreateInfo *VulkanImageCreateInfo,
|
||||
cl_image_format *img_fmt, size_t totalImageSize,
|
||||
size_t &width, size_t &height)
|
||||
cl_int getImageDimensions(const VkImageCreateInfo *VulkanImageCreateInfo,
|
||||
cl_image_format *img_fmt, cl_image_desc *img_desc,
|
||||
VkExtent3D max_ext, const VkSubresourceLayout *layout)
|
||||
{
|
||||
cl_int result = CL_SUCCESS;
|
||||
if (totalImageSize == 0)
|
||||
test_assert_error(
|
||||
VulkanImageCreateInfo != nullptr,
|
||||
"getImageDimensions: invalid VulkanImageCreateInfo pointer!");
|
||||
test_assert_error(img_fmt != nullptr,
|
||||
"getImageDimensions: invalid img_fmt pointer!");
|
||||
test_assert_error(img_desc != nullptr,
|
||||
"getImageDimensions: invalid img_desc pointer!");
|
||||
|
||||
img_desc->image_depth = VulkanImageCreateInfo->extent.depth;
|
||||
img_desc->image_width = VulkanImageCreateInfo->extent.width;
|
||||
img_desc->image_height = VulkanImageCreateInfo->extent.height;
|
||||
|
||||
if (layout != nullptr)
|
||||
{
|
||||
result = CL_INVALID_VALUE;
|
||||
size_t element_size = GetElementNBytes(img_fmt);
|
||||
size_t row_pitch = element_size * VulkanImageCreateInfo->extent.width;
|
||||
row_pitch = row_pitch < layout->rowPitch ? layout->rowPitch : row_pitch;
|
||||
img_desc->image_row_pitch = row_pitch;
|
||||
|
||||
size_t slice_pitch = row_pitch * VulkanImageCreateInfo->extent.height;
|
||||
slice_pitch =
|
||||
slice_pitch < layout->depthPitch ? layout->depthPitch : slice_pitch;
|
||||
img_desc->image_slice_pitch = slice_pitch;
|
||||
}
|
||||
size_t element_size = GetElementNBytes(img_fmt);
|
||||
size_t row_pitch = element_size * VulkanImageCreateInfo->extent.width;
|
||||
row_pitch = row_pitch % 64 == 0 ? row_pitch : ((row_pitch / 64) + 1) * 64;
|
||||
|
||||
width = row_pitch / element_size;
|
||||
height = totalImageSize / row_pitch;
|
||||
switch (img_desc->image_type)
|
||||
{
|
||||
case CL_MEM_OBJECT_IMAGE3D:
|
||||
test_assert_error(img_desc->image_depth >= 1
|
||||
&& img_desc->image_depth <= max_ext.depth,
|
||||
"getImageDimensions: invalid image depth!");
|
||||
case CL_MEM_OBJECT_IMAGE2D:
|
||||
test_assert_error(img_desc->image_height >= 1
|
||||
&& img_desc->image_height <= max_ext.height,
|
||||
"getImageDimensions: invalid image height!");
|
||||
case CL_MEM_OBJECT_IMAGE1D:
|
||||
test_assert_error(img_desc->image_width >= 1
|
||||
&& img_desc->image_width <= max_ext.width,
|
||||
"getImageDimensions: invalid image width!");
|
||||
}
|
||||
|
||||
return result;
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
cl_int
|
||||
getCLImageInfoFromVkImageInfo(const VkImageCreateInfo *VulkanImageCreateInfo,
|
||||
size_t totalImageSize, cl_image_format *img_fmt,
|
||||
cl_image_desc *img_desc)
|
||||
getCLImageInfoFromVkImageInfo(const cl_device_id device,
|
||||
const VkImageCreateInfo *VulkanImageCreateInfo,
|
||||
cl_image_format *img_fmt, cl_image_desc *img_desc,
|
||||
const VkSubresourceLayout *layout)
|
||||
{
|
||||
cl_int result = CL_SUCCESS;
|
||||
cl_int error = CL_SUCCESS;
|
||||
|
||||
cl_image_format clImgFormat = { 0 };
|
||||
result =
|
||||
error =
|
||||
getCLFormatFromVkFormat(VulkanImageCreateInfo->format, &clImgFormat);
|
||||
if (CL_SUCCESS != result)
|
||||
if (CL_SUCCESS != error)
|
||||
{
|
||||
return result;
|
||||
return error;
|
||||
}
|
||||
memcpy(img_fmt, &clImgFormat, sizeof(cl_image_format));
|
||||
|
||||
@@ -469,25 +499,57 @@ getCLImageInfoFromVkImageInfo(const VkImageCreateInfo *VulkanImageCreateInfo,
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
|
||||
result =
|
||||
get2DImageDimensions(VulkanImageCreateInfo, img_fmt, totalImageSize,
|
||||
img_desc->image_width, img_desc->image_height);
|
||||
if (CL_SUCCESS != result)
|
||||
VkExtent3D max_ext = { 0, 0, 0 };
|
||||
|
||||
size_t width = 0, height = 0, depth = 0;
|
||||
if (img_desc->image_type == CL_MEM_OBJECT_IMAGE3D)
|
||||
{
|
||||
throw std::runtime_error("get2DImageDimensions failed!!!");
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_WIDTH,
|
||||
sizeof(width), &width, NULL);
|
||||
test_error(error, "Unable to get CL_DEVICE_IMAGE3D_MAX_WIDTH");
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_HEIGHT,
|
||||
sizeof(height), &height, NULL);
|
||||
test_error(error, "Unable to get CL_DEVICE_IMAGE3D_MAX_HEIGHT");
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_DEPTH,
|
||||
sizeof(depth), &depth, NULL);
|
||||
test_error(error, "Unable to get CL_DEVICE_IMAGE3D_MAX_DEPTH");
|
||||
}
|
||||
else
|
||||
{
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_WIDTH,
|
||||
sizeof(width), &width, NULL);
|
||||
test_error(error, "Unable to get CL_DEVICE_IMAGE2D_MAX_WIDTH");
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_HEIGHT,
|
||||
sizeof(height), &height, NULL);
|
||||
test_error(error, "Unable to get CL_DEVICE_IMAGE2D_MAX_HEIGHT");
|
||||
}
|
||||
|
||||
max_ext.depth = depth;
|
||||
max_ext.height = height;
|
||||
max_ext.width = width;
|
||||
|
||||
// If image_row_pitch is zero and the image is created from an external
|
||||
// memory handle, then the image row pitch is implementation-defined
|
||||
img_desc->image_row_pitch = 0;
|
||||
// If image_slice_pitch is zero and the image is created from an external
|
||||
// memory handle, then the image slice pitch is implementation-defined
|
||||
img_desc->image_slice_pitch = 0;
|
||||
|
||||
error = getImageDimensions(VulkanImageCreateInfo, img_fmt, img_desc,
|
||||
max_ext, layout);
|
||||
if (CL_SUCCESS != error)
|
||||
{
|
||||
throw std::runtime_error("getImageDimensions failed!!!");
|
||||
}
|
||||
|
||||
img_desc->image_depth =
|
||||
static_cast<size_t>(VulkanImageCreateInfo->extent.depth);
|
||||
img_desc->image_array_size = 0;
|
||||
img_desc->image_row_pitch = 0; // Row pitch set to zero as host_ptr is NULL
|
||||
img_desc->image_slice_pitch =
|
||||
img_desc->image_row_pitch * img_desc->image_height;
|
||||
img_desc->num_mip_levels = 0;
|
||||
img_desc->num_samples = 0;
|
||||
img_desc->buffer = NULL;
|
||||
|
||||
return result;
|
||||
return error;
|
||||
}
|
||||
|
||||
cl_int check_external_memory_handle_type(
|
||||
@@ -529,8 +591,8 @@ cl_int check_external_memory_handle_type(
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
|
||||
cl_int check_external_semaphore_handle_type(
|
||||
cl_device_id deviceID,
|
||||
void check_external_semaphore_handle_type(
|
||||
cl_device_id device,
|
||||
cl_external_semaphore_handle_type_khr requiredHandleType,
|
||||
cl_device_info queryParamName)
|
||||
{
|
||||
@@ -540,8 +602,8 @@ cl_int check_external_semaphore_handle_type(
|
||||
cl_int errNum = CL_SUCCESS;
|
||||
|
||||
errNum =
|
||||
clGetDeviceInfo(deviceID, queryParamName, 0, NULL, &handle_type_size);
|
||||
test_error(errNum, "clGetDeviceInfo failed");
|
||||
clGetDeviceInfo(device, queryParamName, 0, NULL, &handle_type_size);
|
||||
ASSERT_SUCCESS(errNum, "clGetDeviceInfo");
|
||||
|
||||
if (handle_type_size == 0)
|
||||
{
|
||||
@@ -549,31 +611,37 @@ cl_int check_external_semaphore_handle_type(
|
||||
queryParamName == CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR
|
||||
? "importing"
|
||||
: "exporting");
|
||||
return CL_INVALID_VALUE;
|
||||
|
||||
throw std::runtime_error("");
|
||||
}
|
||||
|
||||
handle_type =
|
||||
(cl_external_semaphore_handle_type_khr *)malloc(handle_type_size);
|
||||
|
||||
errNum = clGetDeviceInfo(deviceID, queryParamName, handle_type_size,
|
||||
errNum = clGetDeviceInfo(device, queryParamName, handle_type_size,
|
||||
handle_type, NULL);
|
||||
ASSERT_SUCCESS(errNum, "clGetDeviceInfo");
|
||||
|
||||
test_error(
|
||||
errNum,
|
||||
"Unable to query supported device semaphore handle types list\n");
|
||||
|
||||
bool found = false;
|
||||
for (i = 0; i < handle_type_size; i++)
|
||||
{
|
||||
if (requiredHandleType == handle_type[i])
|
||||
{
|
||||
return CL_SUCCESS;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
log_error("cl_khr_external_semaphore extension is missing support for %d\n",
|
||||
requiredHandleType);
|
||||
|
||||
return CL_INVALID_VALUE;
|
||||
if (!found)
|
||||
{
|
||||
log_error("cl_khr_external_semaphore extension is missing support for "
|
||||
"handle type %d\n",
|
||||
requiredHandleType);
|
||||
|
||||
throw std::runtime_error("");
|
||||
}
|
||||
}
|
||||
|
||||
clExternalMemory::clExternalMemory() {}
|
||||
|
||||
clExternalMemory::clExternalMemory(const clExternalMemory &externalMemory)
|
||||
@@ -705,13 +773,17 @@ clExternalMemoryImage::clExternalMemoryImage(
|
||||
std::vector<cl_mem_properties> extMemProperties1;
|
||||
cl_device_id devList[] = { deviceId, NULL };
|
||||
|
||||
VulkanImageTiling vulkanImageTiling =
|
||||
vkClExternalMemoryHandleTilingAssumption(
|
||||
deviceId, externalMemoryHandleType, &errcode_ret);
|
||||
auto vulkanImageTiling = vkClExternalMemoryHandleTilingAssumption(
|
||||
deviceId, externalMemoryHandleType, &errcode_ret);
|
||||
if (CL_SUCCESS != errcode_ret)
|
||||
{
|
||||
throw std::runtime_error("Failed to query OpenCL tiling mode");
|
||||
}
|
||||
if (vulkanImageTiling == std::nullopt)
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"Could not find image tiling supported by both Vulkan and OpenCL");
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!is_extension_available(devList[0], "cl_khr_external_memory_win32"))
|
||||
@@ -796,7 +868,7 @@ clExternalMemoryImage::clExternalMemoryImage(
|
||||
image2D.getVkImageCreateInfo();
|
||||
|
||||
errcode_ret = getCLImageInfoFromVkImageInfo(
|
||||
&VulkanImageCreateInfo, image2D.getSize(), &img_format, &image_desc);
|
||||
deviceId, &VulkanImageCreateInfo, &img_format, &image_desc);
|
||||
if (CL_SUCCESS != errcode_ret)
|
||||
{
|
||||
throw std::runtime_error("getCLImageInfoFromVkImageInfo failed\n");
|
||||
@@ -855,9 +927,15 @@ clExternalImportableSemaphore::clExternalImportableSemaphore(
|
||||
cl_device_id deviceId)
|
||||
: m_deviceSemaphore(semaphore)
|
||||
{
|
||||
|
||||
cl_int err = 0;
|
||||
cl_device_id devList[] = { deviceId, NULL };
|
||||
cl_external_semaphore_handle_type_khr clSemaphoreHandleType =
|
||||
getCLSemaphoreTypeFromVulkanType(externalSemaphoreHandleType);
|
||||
|
||||
check_external_semaphore_handle_type(
|
||||
deviceId, clSemaphoreHandleType,
|
||||
CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR);
|
||||
|
||||
m_externalHandleType = externalSemaphoreHandleType;
|
||||
m_externalSemaphore = nullptr;
|
||||
m_device = deviceId;
|
||||
@@ -875,8 +953,6 @@ clExternalImportableSemaphore::clExternalImportableSemaphore(
|
||||
ASSERT(0);
|
||||
#else
|
||||
fd = (int)semaphore.getHandle(externalSemaphoreHandleType);
|
||||
err = check_external_semaphore_handle_type(
|
||||
devList[0], CL_SEMAPHORE_HANDLE_OPAQUE_FD_KHR);
|
||||
sema_props.push_back(
|
||||
(cl_semaphore_properties_khr)CL_SEMAPHORE_HANDLE_OPAQUE_FD_KHR);
|
||||
sema_props.push_back((cl_semaphore_properties_khr)fd);
|
||||
@@ -888,8 +964,6 @@ clExternalImportableSemaphore::clExternalImportableSemaphore(
|
||||
ASSERT(0);
|
||||
#else
|
||||
handle = semaphore.getHandle(externalSemaphoreHandleType);
|
||||
err = check_external_semaphore_handle_type(
|
||||
devList[0], CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KHR);
|
||||
sema_props.push_back((cl_semaphore_properties_khr)
|
||||
CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KHR);
|
||||
sema_props.push_back((cl_semaphore_properties_khr)handle);
|
||||
@@ -903,8 +977,6 @@ clExternalImportableSemaphore::clExternalImportableSemaphore(
|
||||
const std::wstring &name = semaphore.getName();
|
||||
if (name.size())
|
||||
{
|
||||
err = check_external_semaphore_handle_type(
|
||||
devList[0], CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_NAME_KHR);
|
||||
sema_props.push_back(
|
||||
(cl_semaphore_properties_khr)
|
||||
CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_NAME_KHR);
|
||||
@@ -924,21 +996,17 @@ clExternalImportableSemaphore::clExternalImportableSemaphore(
|
||||
ASSERT(0);
|
||||
#else
|
||||
handle = semaphore.getHandle(externalSemaphoreHandleType);
|
||||
err = check_external_semaphore_handle_type(
|
||||
devList[0], CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KMT_KHR);
|
||||
sema_props.push_back((cl_semaphore_properties_khr)
|
||||
CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KMT_KHR);
|
||||
sema_props.push_back((cl_semaphore_properties_khr)handle);
|
||||
#endif
|
||||
break;
|
||||
case VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD:
|
||||
err = check_external_semaphore_handle_type(
|
||||
devList[0], CL_SEMAPHORE_HANDLE_SYNC_FD_KHR);
|
||||
|
||||
sema_props.push_back(static_cast<cl_semaphore_properties_khr>(
|
||||
CL_SEMAPHORE_HANDLE_SYNC_FD_KHR));
|
||||
sema_props.push_back(static_cast<cl_semaphore_properties_khr>(-1));
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("Unsupported external memory handle type\n");
|
||||
ASSERT(0);
|
||||
@@ -1013,11 +1081,15 @@ clExternalExportableSemaphore::clExternalExportableSemaphore(
|
||||
cl_device_id deviceId)
|
||||
: m_deviceSemaphore(semaphore)
|
||||
{
|
||||
|
||||
cl_int err = 0;
|
||||
cl_device_id devList[] = { deviceId, NULL };
|
||||
cl_external_semaphore_handle_type_khr clSemaphoreHandleType =
|
||||
getCLSemaphoreTypeFromVulkanType(externalSemaphoreHandleType);
|
||||
|
||||
check_external_semaphore_handle_type(
|
||||
deviceId, clSemaphoreHandleType,
|
||||
CL_DEVICE_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR);
|
||||
|
||||
m_externalHandleType = externalSemaphoreHandleType;
|
||||
m_externalSemaphore = nullptr;
|
||||
m_device = deviceId;
|
||||
@@ -1191,6 +1263,10 @@ cl_external_memory_handle_type_khr vkToOpenCLExternalMemoryHandleType(
|
||||
{
|
||||
switch (vkExternalMemoryHandleType)
|
||||
{
|
||||
default:
|
||||
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE:
|
||||
log_error("Unexpected external memory handle type\n");
|
||||
return 0;
|
||||
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD:
|
||||
return CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_FD_KHR;
|
||||
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT:
|
||||
@@ -1198,17 +1274,17 @@ cl_external_memory_handle_type_khr vkToOpenCLExternalMemoryHandleType(
|
||||
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT:
|
||||
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT_KMT:
|
||||
return CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KMT_KHR;
|
||||
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE: return 0;
|
||||
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT_NAME:
|
||||
return CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_NAME_KHR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
VulkanImageTiling vkClExternalMemoryHandleTilingAssumption(
|
||||
std::optional<VulkanImageTiling> vkClExternalMemoryHandleTilingAssumption(
|
||||
cl_device_id deviceId,
|
||||
VulkanExternalMemoryHandleType vkExternalMemoryHandleType, int *error_ret)
|
||||
{
|
||||
size_t size = 0;
|
||||
VulkanImageTiling mode = VULKAN_IMAGE_TILING_OPTIMAL;
|
||||
|
||||
assert(error_ret
|
||||
!= nullptr); // errcode_ret is not optional, it must be checked
|
||||
@@ -1219,12 +1295,12 @@ VulkanImageTiling vkClExternalMemoryHandleTilingAssumption(
|
||||
0, nullptr, &size);
|
||||
if (*error_ret != CL_SUCCESS)
|
||||
{
|
||||
return mode;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
return mode;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::vector<cl_external_memory_handle_type_khr> assume_linear_types(
|
||||
@@ -1236,7 +1312,7 @@ VulkanImageTiling vkClExternalMemoryHandleTilingAssumption(
|
||||
size, assume_linear_types.data(), nullptr);
|
||||
if (*error_ret != CL_SUCCESS)
|
||||
{
|
||||
return mode;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (std::find(
|
||||
@@ -1244,8 +1320,8 @@ VulkanImageTiling vkClExternalMemoryHandleTilingAssumption(
|
||||
vkToOpenCLExternalMemoryHandleType(vkExternalMemoryHandleType))
|
||||
!= assume_linear_types.end())
|
||||
{
|
||||
mode = VULKAN_IMAGE_TILING_LINEAR;
|
||||
return VULKAN_IMAGE_TILING_LINEAR;
|
||||
}
|
||||
|
||||
return mode;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -26,22 +26,7 @@
|
||||
#include <OpenCL/cl_ext.h>
|
||||
#endif
|
||||
|
||||
#define CREATE_OPENCL_SEMAPHORE(clSemaphore, vkSemaphore, ctx, handleType, \
|
||||
devIdx, createExportable) \
|
||||
if (!(createExportable \
|
||||
&& (check_external_semaphore_handle_type( \
|
||||
devIdx, getCLSemaphoreTypeFromVulkanType(handleType), \
|
||||
CL_DEVICE_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR) \
|
||||
== CL_SUCCESS))) \
|
||||
{ \
|
||||
clSemaphore = new clExternalImportableSemaphore(vkSemaphore, ctx, \
|
||||
handleType, devIdx); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
clSemaphore = new clExternalExportableSemaphore(vkSemaphore, ctx, \
|
||||
handleType, devIdx); \
|
||||
}
|
||||
#include <optional>
|
||||
|
||||
typedef cl_semaphore_khr (*pfnclCreateSemaphoreWithPropertiesKHR)(
|
||||
cl_context context, cl_semaphore_properties_khr *sema_props,
|
||||
@@ -86,16 +71,17 @@ extern pfnclEnqueueReleaseExternalMemObjectsKHR
|
||||
extern pfnclReleaseSemaphoreKHR clReleaseSemaphoreKHRptr;
|
||||
extern pfnclReImportSemaphoreSyncFdKHR pfnclReImportSemaphoreSyncFdKHRptr;
|
||||
|
||||
cl_int getCLImageInfoFromVkImageInfo(const VkImageCreateInfo *, size_t,
|
||||
cl_image_format *, cl_image_desc *);
|
||||
cl_int
|
||||
getCLImageInfoFromVkImageInfo(const cl_device_id, const VkImageCreateInfo *,
|
||||
cl_image_format *, cl_image_desc *,
|
||||
const VkSubresourceLayout *layout = nullptr);
|
||||
cl_int check_external_memory_handle_type(
|
||||
cl_device_id deviceID,
|
||||
cl_external_memory_handle_type_khr requiredHandleType);
|
||||
cl_int check_external_semaphore_handle_type(
|
||||
cl_device_id deviceID,
|
||||
void check_external_semaphore_handle_type(
|
||||
cl_device_id device,
|
||||
cl_external_semaphore_handle_type_khr requiredHandleType,
|
||||
cl_device_info queryParamName =
|
||||
CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR);
|
||||
cl_device_info queryParamName);
|
||||
cl_int setMaxImageDimensions(cl_device_id deviceID, size_t &width,
|
||||
size_t &height);
|
||||
|
||||
@@ -187,8 +173,8 @@ public:
|
||||
extern void init_cl_vk_ext(cl_platform_id, cl_uint num_devices,
|
||||
cl_device_id *deviceIds);
|
||||
|
||||
VulkanImageTiling vkClExternalMemoryHandleTilingAssumption(
|
||||
std::optional<VulkanImageTiling> vkClExternalMemoryHandleTilingAssumption(
|
||||
cl_device_id deviceId,
|
||||
VulkanExternalMemoryHandleType vkExternalMemoryHandleType, int *error_ret);
|
||||
|
||||
#endif // _opencl_vulkan_wrapper_hpp_
|
||||
#endif // _opencl_vulkan_wrapper_hpp_
|
||||
|
||||
@@ -102,6 +102,8 @@
|
||||
VK_FUNC_DECL(vkImportSemaphoreFdKHR) \
|
||||
VK_FUNC_DECL(vkGetPhysicalDeviceExternalSemaphorePropertiesKHR) \
|
||||
VK_FUNC_DECL(vkGetImageSubresourceLayout) \
|
||||
VK_FUNC_DECL(vkCreateDebugUtilsMessengerEXT) \
|
||||
VK_FUNC_DECL(vkDestroyDebugUtilsMessengerEXT) \
|
||||
VK_FUNC_DECL(vkGetPhysicalDeviceExternalBufferProperties)
|
||||
#define VK_WINDOWS_FUNC_LIST \
|
||||
VK_FUNC_DECL(vkGetMemoryWin32HandleKHR) \
|
||||
@@ -203,6 +205,8 @@
|
||||
#define vkGetSemaphoreWin32HandleKHR _vkGetSemaphoreWin32HandleKHR
|
||||
#define vkImportSemaphoreWin32HandleKHR _vkImportSemaphoreWin32HandleKHR
|
||||
#define vkGetImageSubresourceLayout _vkGetImageSubresourceLayout
|
||||
#define vkCreateDebugUtilsMessengerEXT _vkCreateDebugUtilsMessengerEXT
|
||||
#define vkDestroyDebugUtilsMessengerEXT _vkDestroyDebugUtilsMessengerEXT
|
||||
#define vkGetPhysicalDeviceExternalBufferProperties \
|
||||
_vkGetPhysicalDeviceExternalBufferProperties
|
||||
|
||||
|
||||
@@ -32,13 +32,13 @@
|
||||
#define BUFFERSIZE 3000
|
||||
|
||||
|
||||
const VulkanInstance &getVulkanInstance()
|
||||
const VulkanInstance &getVulkanInstance(bool useValidationLayers)
|
||||
{
|
||||
static VulkanInstance instance;
|
||||
static VulkanInstance instance(useValidationLayers);
|
||||
return instance;
|
||||
}
|
||||
|
||||
const VulkanPhysicalDevice &getVulkanPhysicalDevice()
|
||||
const VulkanPhysicalDevice &getVulkanPhysicalDevice(bool useValidationLayers)
|
||||
{
|
||||
size_t pdIdx = 0;
|
||||
cl_int errNum = 0;
|
||||
@@ -47,7 +47,7 @@ const VulkanPhysicalDevice &getVulkanPhysicalDevice()
|
||||
cl_uint num_devices = 0;
|
||||
cl_uint device_no = 0;
|
||||
const size_t bufsize = BUFFERSIZE;
|
||||
const VulkanInstance &instance = getVulkanInstance();
|
||||
const VulkanInstance &instance = getVulkanInstance(useValidationLayers);
|
||||
const VulkanPhysicalDeviceList &physicalDeviceList =
|
||||
instance.getPhysicalDeviceList();
|
||||
|
||||
@@ -112,12 +112,13 @@ const VulkanPhysicalDevice &getVulkanPhysicalDevice()
|
||||
}
|
||||
|
||||
const VulkanPhysicalDevice &
|
||||
getAssociatedVulkanPhysicalDevice(cl_device_id deviceId)
|
||||
getAssociatedVulkanPhysicalDevice(cl_device_id deviceId,
|
||||
bool useValidationLayers)
|
||||
{
|
||||
size_t pdIdx;
|
||||
cl_int errNum = 0;
|
||||
cl_uchar uuid[CL_UUID_SIZE_KHR];
|
||||
const VulkanInstance &instance = getVulkanInstance();
|
||||
const VulkanInstance &instance = getVulkanInstance(useValidationLayers);
|
||||
const VulkanPhysicalDeviceList &physicalDeviceList =
|
||||
instance.getPhysicalDeviceList();
|
||||
|
||||
@@ -188,10 +189,10 @@ getVulkanMemoryType(const VulkanDevice &device,
|
||||
return memoryTypeList[mtIdx];
|
||||
}
|
||||
|
||||
bool checkVkSupport()
|
||||
bool checkVkSupport(bool useValidationLayers)
|
||||
{
|
||||
bool result = true;
|
||||
const VulkanInstance &instance = getVulkanInstance();
|
||||
const VulkanInstance &instance = getVulkanInstance(useValidationLayers);
|
||||
const VulkanPhysicalDeviceList &physicalDeviceList =
|
||||
instance.getPhysicalDeviceList();
|
||||
if (physicalDeviceList() == NULL)
|
||||
@@ -711,6 +712,7 @@ operator<<(std::ostream &os,
|
||||
{
|
||||
switch (externalMemoryHandleType)
|
||||
{
|
||||
default:
|
||||
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE: return os << "None";
|
||||
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD:
|
||||
return os << "Opaque file descriptor";
|
||||
@@ -731,6 +733,7 @@ operator<<(std::ostream &os,
|
||||
{
|
||||
switch (externalSemaphoreHandleType)
|
||||
{
|
||||
default:
|
||||
case VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_NONE: return os << "None";
|
||||
case VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD:
|
||||
return os << "Opaque file descriptor";
|
||||
|
||||
@@ -30,10 +30,12 @@
|
||||
#define ROUND_UP(n, multiple) \
|
||||
(((n) + (multiple)-1) - ((((n) + (multiple)-1)) % (multiple)))
|
||||
|
||||
const VulkanInstance& getVulkanInstance();
|
||||
const VulkanPhysicalDevice& getVulkanPhysicalDevice();
|
||||
const VulkanInstance& getVulkanInstance(bool useValidationLayers = false);
|
||||
const VulkanPhysicalDevice&
|
||||
getAssociatedVulkanPhysicalDevice(cl_device_id deviceId);
|
||||
getVulkanPhysicalDevice(bool useValidationLayers = false);
|
||||
const VulkanPhysicalDevice&
|
||||
getAssociatedVulkanPhysicalDevice(cl_device_id deviceId,
|
||||
bool useValidationLayers = false);
|
||||
const VulkanQueueFamily& getVulkanQueueFamily(
|
||||
const VulkanPhysicalDevice& physicalDevice = getVulkanPhysicalDevice(),
|
||||
uint32_t queueFlags = VULKAN_QUEUE_FLAG_GRAPHICS
|
||||
@@ -41,7 +43,7 @@ const VulkanQueueFamily& getVulkanQueueFamily(
|
||||
const VulkanMemoryType&
|
||||
getVulkanMemoryType(const VulkanDevice& device,
|
||||
VulkanMemoryTypeProperty memoryTypeProperty);
|
||||
bool checkVkSupport();
|
||||
bool checkVkSupport(bool useValidationLayers = false);
|
||||
const VulkanQueueFamilyList& getEmptyVulkanQueueFamilyList();
|
||||
const VulkanDescriptorSetLayoutList& getEmptyVulkanDescriptorSetLayoutList();
|
||||
const VulkanQueueFamilyToQueueCountMap&
|
||||
|
||||
@@ -48,16 +48,38 @@ VK_WINDOWS_FUNC_LIST
|
||||
|
||||
#define CHECK_VK(call) \
|
||||
if (call != VK_SUCCESS) return call;
|
||||
|
||||
static VKAPI_ATTR VkBool32 VKAPI_CALL logCallback(
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData)
|
||||
{
|
||||
switch (messageSeverity)
|
||||
{
|
||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
|
||||
log_error("Vulkan validation layer: %s\n", pCallbackData->pMessage);
|
||||
break;
|
||||
default:
|
||||
log_info("Vulkan validation layer: %s\n", pCallbackData->pMessage);
|
||||
break;
|
||||
}
|
||||
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
// VulkanInstance implementation //
|
||||
///////////////////////////////////
|
||||
|
||||
VulkanInstance::VulkanInstance(const VulkanInstance &instance)
|
||||
: m_vkInstance(instance.m_vkInstance),
|
||||
m_physicalDeviceList(instance.m_physicalDeviceList)
|
||||
m_physicalDeviceList(instance.m_physicalDeviceList),
|
||||
m_useValidationLayers(instance.m_useValidationLayers),
|
||||
m_validationLayers(instance.m_validationLayers)
|
||||
{}
|
||||
|
||||
VulkanInstance::VulkanInstance(): m_vkInstance(VK_NULL_HANDLE)
|
||||
VulkanInstance::VulkanInstance(bool useValidationLayers)
|
||||
: m_vkInstance(VK_NULL_HANDLE), m_useValidationLayers(useValidationLayers)
|
||||
{
|
||||
#if defined(__linux__) && !defined(__ANDROID__)
|
||||
char *glibcVersion = strdup(gnu_get_libc_version());
|
||||
@@ -130,6 +152,35 @@ VulkanInstance::VulkanInstance(): m_vkInstance(VK_NULL_HANDLE)
|
||||
VK_GET_NULL_INSTANCE_PROC_ADDR(vkCreateInstance);
|
||||
#undef VK_GET_NULL_INSTANCE_PROC_ADDR
|
||||
|
||||
if (m_useValidationLayers)
|
||||
{
|
||||
uint32_t layerCount = 0;
|
||||
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
|
||||
|
||||
std::vector<VkLayerProperties> layers(layerCount);
|
||||
vkEnumerateInstanceLayerProperties(&layerCount, layers.data());
|
||||
|
||||
for (auto it = m_validationLayers.begin();
|
||||
it != m_validationLayers.end();)
|
||||
{
|
||||
bool found = false;
|
||||
for (const auto &layerProps : layers)
|
||||
if (strcmp(*it, layerProps.layerName) == 0)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
log_info("Vulkan layer not found: %s\n", *it);
|
||||
it = m_validationLayers.erase(it);
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
m_useValidationLayers = !m_validationLayers.empty();
|
||||
}
|
||||
|
||||
VkApplicationInfo vkApplicationInfo = {};
|
||||
vkApplicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
vkApplicationInfo.pNext = NULL;
|
||||
@@ -147,6 +198,9 @@ VulkanInstance::VulkanInstance(): m_vkInstance(VK_NULL_HANDLE)
|
||||
enabledExtensionNameList.push_back(
|
||||
VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
|
||||
|
||||
if (m_useValidationLayers)
|
||||
enabledExtensionNameList.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
|
||||
std::vector<VkExtensionProperties> vkExtensionPropertiesList(
|
||||
instanceExtensionPropertiesCount);
|
||||
vkEnumerateInstanceExtensionProperties(NULL,
|
||||
@@ -174,18 +228,51 @@ VulkanInstance::VulkanInstance(): m_vkInstance(VK_NULL_HANDLE)
|
||||
|
||||
VkInstanceCreateInfo vkInstanceCreateInfo = {};
|
||||
vkInstanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
vkInstanceCreateInfo.pNext = NULL;
|
||||
vkInstanceCreateInfo.flags = 0;
|
||||
vkInstanceCreateInfo.pApplicationInfo = &vkApplicationInfo;
|
||||
vkInstanceCreateInfo.enabledLayerCount = 0;
|
||||
vkInstanceCreateInfo.ppEnabledLayerNames = NULL;
|
||||
vkInstanceCreateInfo.enabledExtensionCount =
|
||||
(uint32_t)enabledExtensionNameList.size();
|
||||
vkInstanceCreateInfo.ppEnabledExtensionNames =
|
||||
enabledExtensionNameList.data();
|
||||
vkInstanceCreateInfo.enabledLayerCount = 0;
|
||||
vkInstanceCreateInfo.pNext = NULL;
|
||||
|
||||
VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo{};
|
||||
if (m_useValidationLayers)
|
||||
{
|
||||
vkInstanceCreateInfo.enabledLayerCount =
|
||||
static_cast<uint32_t>(m_validationLayers.size());
|
||||
vkInstanceCreateInfo.ppEnabledLayerNames = m_validationLayers.data();
|
||||
|
||||
debugCreateInfo.messageType =
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT
|
||||
| VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
|
||||
| VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
|
||||
|
||||
debugCreateInfo.sType =
|
||||
VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
||||
debugCreateInfo.messageSeverity =
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
|
||||
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
||||
debugCreateInfo.pfnUserCallback = logCallback;
|
||||
|
||||
vkInstanceCreateInfo.pNext =
|
||||
(VkDebugUtilsMessengerCreateInfoEXT *)&debugCreateInfo;
|
||||
}
|
||||
|
||||
vkCreateInstance(&vkInstanceCreateInfo, NULL, &m_vkInstance);
|
||||
|
||||
if (m_useValidationLayers)
|
||||
{
|
||||
_vkCreateDebugUtilsMessengerEXT =
|
||||
(PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(
|
||||
m_vkInstance, "vkCreateDebugUtilsMessengerEXT");
|
||||
if (_vkCreateDebugUtilsMessengerEXT != nullptr)
|
||||
vkCreateDebugUtilsMessengerEXT(m_vkInstance, &debugCreateInfo,
|
||||
nullptr, &m_debugMessenger);
|
||||
}
|
||||
|
||||
#define VK_FUNC_DECL(name) \
|
||||
_##name = (PFN_##name)vkGetInstanceProcAddr(m_vkInstance, #name); \
|
||||
// ASSERT_NEQ((unsigned long long)name, 0ULL) << "Couldn't obtain address
|
||||
@@ -228,6 +315,17 @@ VulkanInstance::~VulkanInstance()
|
||||
m_physicalDeviceList[pdIdx];
|
||||
delete &physicalDevice;
|
||||
}
|
||||
|
||||
_vkDestroyDebugUtilsMessengerEXT =
|
||||
(PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(
|
||||
m_vkInstance, "vkDestroyDebugUtilsMessengerEXT");
|
||||
|
||||
if (_vkDestroyDebugUtilsMessengerEXT != nullptr)
|
||||
{
|
||||
vkDestroyDebugUtilsMessengerEXT(m_vkInstance, m_debugMessenger,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
if (m_vkInstance)
|
||||
{
|
||||
vkDestroyInstance(m_vkInstance, NULL);
|
||||
@@ -1741,7 +1839,13 @@ VulkanImage::VulkanImage(
|
||||
vkImageCreateInfo.pNext = &vkExternalMemoryImageCreateInfo;
|
||||
}
|
||||
|
||||
vkCreateImage(m_device, &vkImageCreateInfo, NULL, &m_vkImage);
|
||||
VkResult vkStatus =
|
||||
vkCreateImage(m_device, &vkImageCreateInfo, NULL, &m_vkImage);
|
||||
if (vkStatus != VK_SUCCESS)
|
||||
{
|
||||
throw std::runtime_error("Error: Failed create image.");
|
||||
}
|
||||
|
||||
VulkanImageCreateInfo = vkImageCreateInfo;
|
||||
|
||||
VkMemoryDedicatedRequirements vkMemoryDedicatedRequirements = {};
|
||||
@@ -1870,7 +1974,7 @@ VulkanExtent3D VulkanImage2D::getExtent3D(uint32_t mipLevel) const
|
||||
return VulkanExtent3D(width, height, depth);
|
||||
}
|
||||
|
||||
VkSubresourceLayout VulkanImage2D::getSubresourceLayout() const
|
||||
VkSubresourceLayout VulkanImage::getSubresourceLayout() const
|
||||
{
|
||||
VkImageSubresource subresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 };
|
||||
|
||||
|
||||
@@ -25,14 +25,21 @@
|
||||
#include <cassert>
|
||||
|
||||
class VulkanInstance {
|
||||
friend const VulkanInstance &getVulkanInstance();
|
||||
friend const VulkanInstance &getVulkanInstance(bool useValidationLayers);
|
||||
|
||||
protected:
|
||||
VkInstance m_vkInstance;
|
||||
VulkanPhysicalDeviceList m_physicalDeviceList;
|
||||
VkDebugUtilsMessengerEXT m_debugMessenger;
|
||||
bool m_useValidationLayers;
|
||||
std::vector<const char *> m_validationLayers = {
|
||||
"VK_LAYER_KHRONOS_validation",
|
||||
};
|
||||
|
||||
VulkanInstance();
|
||||
VulkanInstance(const VulkanInstance &);
|
||||
|
||||
public:
|
||||
VulkanInstance(bool useValidationLayers = false);
|
||||
virtual ~VulkanInstance();
|
||||
|
||||
public:
|
||||
@@ -478,12 +485,14 @@ public:
|
||||
VulkanExternalMemoryHandleType externalMemoryHandleType =
|
||||
VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE,
|
||||
VulkanImageCreateFlag imageCreateFlags = VULKAN_IMAGE_CREATE_FLAG_NONE,
|
||||
VulkanImageTiling imageTiling = VULKAN_IMAGE_TILING_OPTIMAL,
|
||||
VulkanImageTiling imageTiling = VULKAN_IMAGE_TILING_LINEAR,
|
||||
VulkanImageUsage imageUsage =
|
||||
VULKAN_IMAGE_USAGE_SAMPLED_STORAGE_TRANSFER_SRC_DST,
|
||||
VulkanSharingMode sharingMode = VULKAN_SHARING_MODE_EXCLUSIVE);
|
||||
virtual ~VulkanImage();
|
||||
virtual VulkanExtent3D getExtent3D(uint32_t mipLevel = 0) const;
|
||||
virtual VkSubresourceLayout getSubresourceLayout() const;
|
||||
|
||||
VulkanFormat getFormat() const;
|
||||
uint32_t getNumMipLevels() const;
|
||||
uint32_t getNumLayers() const;
|
||||
@@ -553,7 +562,6 @@ public:
|
||||
VulkanSharingMode sharingMode = VULKAN_SHARING_MODE_EXCLUSIVE);
|
||||
virtual ~VulkanImage2D();
|
||||
virtual VulkanExtent3D getExtent3D(uint32_t mipLevel = 0) const;
|
||||
virtual VkSubresourceLayout getSubresourceLayout() const;
|
||||
|
||||
VulkanImage2D(const VulkanImage2D &image2D);
|
||||
};
|
||||
|
||||
@@ -45,27 +45,4 @@
|
||||
}
|
||||
|
||||
|
||||
// scope guard helper to ensure proper releasing of sub devices
|
||||
struct SubDevicesScopeGuarded
|
||||
{
|
||||
SubDevicesScopeGuarded(const cl_int dev_count)
|
||||
{
|
||||
sub_devices.resize(dev_count);
|
||||
}
|
||||
~SubDevicesScopeGuarded()
|
||||
{
|
||||
for (auto &device : sub_devices)
|
||||
{
|
||||
cl_int err = clReleaseDevice(device);
|
||||
if (err != CL_SUCCESS)
|
||||
log_error("\n Releasing sub-device failed \n");
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<cl_device_id> sub_devices;
|
||||
};
|
||||
|
||||
#endif // _testBase_h
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ const char *sample_kernel_code_two_line[] = {
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
|
||||
const char *sample_kernel_code_bad_multi_line[] = {
|
||||
"__kernel void sample_test(__global float *src, __global int *dst)",
|
||||
"{",
|
||||
@@ -87,6 +86,35 @@ __kernel void sample_test_C(__global float *src, __global int *dst)
|
||||
}
|
||||
)";
|
||||
|
||||
const char *sample_multi_kernel_code_AB_with_macro = R"(
|
||||
__kernel void sample_test_A(__global float *src, __global int *dst)
|
||||
{
|
||||
size_t tid = get_global_id(0);
|
||||
dst[tid] = (int)src[tid];
|
||||
}
|
||||
#ifdef USE_SAMPLE_TEST_B
|
||||
__kernel void sample_test_B(__global float *src, __global int *dst)
|
||||
{
|
||||
size_t tid = get_global_id(0);
|
||||
dst[tid] = (int)src[tid];
|
||||
}
|
||||
#endif
|
||||
)";
|
||||
|
||||
const char *sample_multi_kernel_code_CD_with_macro = R"(
|
||||
__kernel void sample_test_C(__global float *src, __global int *dst)
|
||||
{
|
||||
size_t tid = get_global_id(0);
|
||||
dst[tid] = (int)src[tid];
|
||||
}
|
||||
#ifdef USE_SAMPLE_TEST_D
|
||||
__kernel void sample_test_D(__global float *src, __global int *dst)
|
||||
{
|
||||
size_t tid = get_global_id(0);
|
||||
dst[tid] = (int)src[tid];
|
||||
}
|
||||
#endif
|
||||
)";
|
||||
|
||||
REGISTER_TEST(load_program_source)
|
||||
{
|
||||
@@ -550,6 +578,128 @@ REGISTER_TEST(get_program_info_kernel_names)
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
REGISTER_TEST(get_linked_program_info_kernel_names)
|
||||
{
|
||||
int error = CL_SUCCESS;
|
||||
size_t total_kernels = 0;
|
||||
size_t kernel_names_len = 0;
|
||||
|
||||
clProgramWrapper program_AB = clCreateProgramWithSource(
|
||||
context, 1, &sample_multi_kernel_code_AB_with_macro, nullptr, &error);
|
||||
test_error(error, "clCreateProgramWithSource failed");
|
||||
|
||||
clProgramWrapper program_CD = clCreateProgramWithSource(
|
||||
context, 1, &sample_multi_kernel_code_CD_with_macro, nullptr, &error);
|
||||
test_error(error, "clCreateProgramWithSource failed");
|
||||
|
||||
clProgramWrapper program = nullptr;
|
||||
|
||||
// 1) Compile and link the programs with the preprocessor macro undefined.
|
||||
// Query CL_PROGRAM_NUM_KERNELS and check that the correct number is
|
||||
// returned. Query CL_PROGRAM_KERNEL_NAMES and check that the right
|
||||
// kernel names are returned.
|
||||
{
|
||||
error =
|
||||
clCompileProgram(program_AB, 1, &device, nullptr, 0, 0, 0, 0, 0);
|
||||
test_error(error, "clCompileProgram failed");
|
||||
|
||||
error =
|
||||
clCompileProgram(program_CD, 1, &device, nullptr, 0, 0, 0, 0, 0);
|
||||
test_error(error, "clCompileProgram failed");
|
||||
|
||||
cl_program progs[] = { program_AB, program_CD };
|
||||
program =
|
||||
clLinkProgram(context, 1, &device, "", 2, progs, 0, 0, &error);
|
||||
test_error(error, "clLinkProgram failed");
|
||||
|
||||
error = clGetProgramInfo(program, CL_PROGRAM_NUM_KERNELS,
|
||||
sizeof(size_t), &total_kernels, nullptr);
|
||||
test_error(error, "clGetProgramInfo failed");
|
||||
|
||||
test_assert_error(total_kernels == 2,
|
||||
"Unexpected clGetProgramInfo result");
|
||||
|
||||
error = clGetProgramInfo(program, CL_PROGRAM_KERNEL_NAMES, 0, nullptr,
|
||||
&kernel_names_len);
|
||||
test_error(error, "clGetProgramInfo failed");
|
||||
|
||||
const size_t len = kernel_names_len + 1;
|
||||
std::vector<char> kernel_names(len, '\0');
|
||||
error =
|
||||
clGetProgramInfo(program, CL_PROGRAM_KERNEL_NAMES, kernel_names_len,
|
||||
kernel_names.data(), &kernel_names_len);
|
||||
test_error(error, "Unable to get kernel names list.");
|
||||
std::string program_names = kernel_names.data();
|
||||
|
||||
std::vector<std::string> expected_names = { "sample_test_A",
|
||||
"sample_test_C" };
|
||||
for (const auto &name : expected_names)
|
||||
{
|
||||
test_assert_error(program_names.find(name) != std::string::npos,
|
||||
"Unexpected kernel name");
|
||||
}
|
||||
|
||||
std::vector<std::string> unexpected_names = { "sample_test_B",
|
||||
"sample_test_D" };
|
||||
for (const auto &name : unexpected_names)
|
||||
{
|
||||
test_assert_error(program_names.find(name) == std::string::npos,
|
||||
"Unexpected kernel name");
|
||||
}
|
||||
}
|
||||
|
||||
// 2) Compile and link the programs with the preprocessor macro defined.
|
||||
// Query CL_PROGRAM_NUM_KERNELS and check that the correct number is
|
||||
// returned. Query CL_PROGRAM_KERNEL_NAMES and check that the right
|
||||
// kernel names are returned.
|
||||
{
|
||||
const char *build_options_B = "-DUSE_SAMPLE_TEST_B";
|
||||
error = clCompileProgram(program_AB, 1, &device, build_options_B, 0, 0,
|
||||
0, 0, 0);
|
||||
test_error(error, "clCompileProgram failed");
|
||||
|
||||
const char *build_options_D = "-DUSE_SAMPLE_TEST_D";
|
||||
error = clCompileProgram(program_CD, 1, &device, build_options_D, 0, 0,
|
||||
0, 0, 0);
|
||||
test_error(error, "clCompileProgram failed");
|
||||
|
||||
cl_program progs[] = { program_AB, program_CD };
|
||||
program =
|
||||
clLinkProgram(context, 1, &device, "", 2, progs, 0, 0, &error);
|
||||
test_error(error, "clLinkProgram failed");
|
||||
|
||||
error = clGetProgramInfo(program, CL_PROGRAM_NUM_KERNELS,
|
||||
sizeof(size_t), &total_kernels, nullptr);
|
||||
test_error(error, "clGetProgramInfo failed");
|
||||
|
||||
test_assert_error(total_kernels == 4,
|
||||
"Unexpected clGetProgramInfo result");
|
||||
|
||||
error = clGetProgramInfo(program, CL_PROGRAM_KERNEL_NAMES, 0, nullptr,
|
||||
&kernel_names_len);
|
||||
test_error(error, "clGetProgramInfo failed");
|
||||
|
||||
std::vector<std::string> expected_names = {
|
||||
"sample_test_A", "sample_test_B", "sample_test_C", "sample_test_D"
|
||||
};
|
||||
|
||||
const size_t len = kernel_names_len + 1;
|
||||
std::vector<char> kernel_names(len, '\0');
|
||||
error =
|
||||
clGetProgramInfo(program, CL_PROGRAM_KERNEL_NAMES, kernel_names_len,
|
||||
kernel_names.data(), &kernel_names_len);
|
||||
test_error(error, "Could not find expected kernel name");
|
||||
|
||||
std::string program_names = kernel_names.data();
|
||||
for (const auto &name : expected_names)
|
||||
{
|
||||
test_assert_error(program_names.find(name) != std::string::npos,
|
||||
"Unexpected kernel name");
|
||||
}
|
||||
}
|
||||
return TEST_PASS;
|
||||
}
|
||||
|
||||
REGISTER_TEST(get_program_info_mult_devices)
|
||||
{
|
||||
size_t size = 0;
|
||||
@@ -641,7 +791,7 @@ REGISTER_TEST(get_program_info_mult_devices)
|
||||
if (program == nullptr)
|
||||
{
|
||||
log_error("ERROR: Unable to create reference program!\n");
|
||||
return -1;
|
||||
return TEST_FAIL;
|
||||
}
|
||||
|
||||
err = clGetProgramInfo(program, CL_PROGRAM_NUM_DEVICES, sizeof(num_devices),
|
||||
@@ -670,7 +820,7 @@ REGISTER_TEST(get_program_info_mult_devices)
|
||||
}
|
||||
}
|
||||
test_error_fail(
|
||||
!found, "Unexpected result returned by CL_CONTEXT_DEVICES query");
|
||||
!found, "Unexpected result returned by CL_PROGRAM_DEVICES query");
|
||||
}
|
||||
|
||||
return TEST_PASS;
|
||||
|
||||
@@ -94,7 +94,8 @@ const char *known_extensions[] = {
|
||||
"cl_khr_external_memory_dma_buf",
|
||||
"cl_khr_command_buffer",
|
||||
"cl_khr_command_buffer_mutable_dispatch",
|
||||
"cl_khr_command_buffer_multi_device"
|
||||
"cl_khr_command_buffer_multi_device",
|
||||
"cl_khr_external_memory_android_hardware_buffer"
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -56,9 +56,9 @@ static int test_CL_DEVICE_OPENCL_C_VERSION(cl_device_id device,
|
||||
// For OpenCL 2.x, the minimum required OpenCL C version is OpenCL C 2.0.
|
||||
// For other OpenCL versions, the minimum required OpenCL C version is
|
||||
// the same as the API version.
|
||||
const Version min_clc_version = api_version == Version(3, 0)
|
||||
? Version(1, 2)
|
||||
: api_version >= Version(2, 0) ? Version(2, 0) : api_version;
|
||||
const Version min_clc_version = api_version == Version(3, 0) ? Version(1, 2)
|
||||
: api_version >= Version(2, 0) ? Version(2, 0)
|
||||
: api_version;
|
||||
if (clc_version < min_clc_version)
|
||||
{
|
||||
log_error("The minimum required OpenCL C version for API version %s is "
|
||||
@@ -88,10 +88,10 @@ static int test_CL_DEVICE_OPENCL_C_VERSION(cl_device_id device,
|
||||
if (clc_version >= testcase.version)
|
||||
{
|
||||
clProgramWrapper program;
|
||||
cl_int error =
|
||||
create_single_kernel_helper_create_program_for_device(
|
||||
context, device, &program, 1, &test_kernel,
|
||||
testcase.buildOptions);
|
||||
clKernelWrapper kernel;
|
||||
cl_int error = create_single_kernel_helper(
|
||||
context, &program, &kernel, 1, &test_kernel, "test",
|
||||
testcase.buildOptions);
|
||||
test_error(error, "Unable to build program!");
|
||||
|
||||
log_info(" successfully built program with build options '%s'\n",
|
||||
@@ -152,9 +152,10 @@ static int test_CL_DEVICE_OPENCL_C_ALL_VERSIONS(cl_device_id device,
|
||||
buildOptions += std::to_string(minor);
|
||||
|
||||
clProgramWrapper program;
|
||||
error = create_single_kernel_helper_create_program_for_device(
|
||||
context, device, &program, 1, &test_kernel,
|
||||
buildOptions.c_str());
|
||||
clKernelWrapper kernel;
|
||||
error = create_single_kernel_helper(context, &program, &kernel, 1,
|
||||
&test_kernel, "test",
|
||||
buildOptions.c_str());
|
||||
test_error(error, "Unable to build program!");
|
||||
|
||||
log_info(" successfully built program with build options '%s'\n",
|
||||
|
||||
@@ -12,6 +12,6 @@ if("${CLConform_TARGET_ARCH}" STREQUAL "ARM" OR "${CLConform_TARGET_ARCH}" STREQ
|
||||
list(APPEND ${MODULE_NAME}_SOURCES fplib.cpp)
|
||||
endif()
|
||||
|
||||
set_gnulike_module_compile_flags("-Wno-sign-compare -Wno-format")
|
||||
set_gnulike_module_compile_flags("-Wno-sign-compare")
|
||||
|
||||
include(../CMakeCommon.txt)
|
||||
|
||||
@@ -68,12 +68,6 @@ cl_context gContext = NULL;
|
||||
cl_command_queue gQueue = NULL;
|
||||
int gStartTestNumber = -1;
|
||||
int gEndTestNumber = 0;
|
||||
#if defined(__APPLE__)
|
||||
int gTimeResults = 1;
|
||||
#else
|
||||
int gTimeResults = 0;
|
||||
#endif
|
||||
int gReportAverageTimes = 0;
|
||||
void *gIn = NULL;
|
||||
void *gRef = NULL;
|
||||
void *gAllowZ = NULL;
|
||||
@@ -103,8 +97,6 @@ const char **argList = NULL;
|
||||
int argCount = 0;
|
||||
|
||||
|
||||
double SubtractTime(uint64_t endTime, uint64_t startTime);
|
||||
|
||||
cl_half_rounding_mode DataInitInfo::halfRoundingMode = CL_HALF_RTE;
|
||||
cl_half_rounding_mode ConversionsTest::defaultHalfRoundingMode = CL_HALF_RTE;
|
||||
|
||||
@@ -318,7 +310,7 @@ int CalcRefValsPat<InType, OutType, InFP, OutFP>::check_result(void *test,
|
||||
{
|
||||
const cl_uchar *a = (const cl_uchar *)gAllowZ;
|
||||
|
||||
if (is_half<OutType, OutFP>())
|
||||
if constexpr (is_half<OutType, OutFP>())
|
||||
{
|
||||
const cl_half *t = (const cl_half *)test;
|
||||
const cl_half *c = (const cl_half *)gRef;
|
||||
@@ -335,7 +327,7 @@ int CalcRefValsPat<InType, OutType, InFP, OutFP>::check_result(void *test,
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
else if (std::is_integral<OutType>::value)
|
||||
else if constexpr (std::is_integral<OutType>::value)
|
||||
{ // char/uchar/short/ushort/half/int/uint/long/ulong
|
||||
const OutType *t = (const OutType *)test;
|
||||
const OutType *c = (const OutType *)gRef;
|
||||
@@ -350,7 +342,7 @@ int CalcRefValsPat<InType, OutType, InFP, OutFP>::check_result(void *test,
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
else if (std::is_same<OutType, cl_float>::value)
|
||||
else if constexpr (std::is_same<OutType, cl_float>::value)
|
||||
{
|
||||
// cast to integral - from original test
|
||||
const cl_uint *t = (const cl_uint *)test;
|
||||
@@ -904,61 +896,6 @@ int ConversionsTest::DoTest(Type outType, Type inType, SaturationMode sat,
|
||||
|
||||
log_info("done.\n");
|
||||
|
||||
if (gTimeResults)
|
||||
{
|
||||
// Kick off tests for the various vector lengths
|
||||
for (vectorSize = gMinVectorSize; vectorSize < gMaxVectorSize;
|
||||
vectorSize++)
|
||||
{
|
||||
size_t workItemCount = blockCount / vectorSizes[vectorSize];
|
||||
if (vectorSizes[vectorSize] * gTypeSizes[outType] < 4)
|
||||
workItemCount /=
|
||||
4 / (vectorSizes[vectorSize] * gTypeSizes[outType]);
|
||||
|
||||
double sum = 0.0;
|
||||
double bestTime = INFINITY;
|
||||
cl_uint k;
|
||||
for (k = 0; k < PERF_LOOP_COUNT; k++)
|
||||
{
|
||||
uint64_t startTime = conv_test::GetTime();
|
||||
if ((error = conv_test::RunKernel(
|
||||
writeInputBufferInfo.calcInfo[vectorSize]->kernel,
|
||||
gInBuffer, gOutBuffers[vectorSize], workItemCount)))
|
||||
{
|
||||
gFailCount++;
|
||||
return error;
|
||||
}
|
||||
|
||||
// Make sure OpenCL is done
|
||||
if ((error = clFinish(gQueue)))
|
||||
{
|
||||
vlog_error("Error %d at clFinish\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
uint64_t endTime = conv_test::GetTime();
|
||||
double time = SubtractTime(endTime, startTime);
|
||||
sum += time;
|
||||
if (time < bestTime) bestTime = time;
|
||||
}
|
||||
|
||||
if (gReportAverageTimes) bestTime = sum / PERF_LOOP_COUNT;
|
||||
double clocksPerOp = bestTime * (double)gDeviceFrequency
|
||||
* gComputeDevices * gSimdSize * 1e6
|
||||
/ (workItemCount * vectorSizes[vectorSize]);
|
||||
if (0 == vectorSize)
|
||||
vlog_perf(clocksPerOp, LOWER_IS_BETTER, "clocks / element",
|
||||
"implicit convert %s -> %s", gTypeNames[inType],
|
||||
gTypeNames[outType]);
|
||||
else
|
||||
vlog_perf(clocksPerOp, LOWER_IS_BETTER, "clocks / element",
|
||||
"convert_%s%s%s%s( %s%s )", gTypeNames[outType],
|
||||
sizeNames[vectorSize], gSaturationNames[sat],
|
||||
gRoundingModeNames[round], gTypeNames[inType],
|
||||
sizeNames[vectorSize]);
|
||||
}
|
||||
}
|
||||
|
||||
if (gWimpyMode)
|
||||
vlog("\tWimp pass");
|
||||
else
|
||||
@@ -978,33 +915,6 @@ int ConversionsTest::DoTest(Type outType, Type inType, SaturationMode sat,
|
||||
void memset_pattern4(void *dest, const void *src_pattern, size_t bytes);
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
/* function is defined in "compat.h" */
|
||||
#else
|
||||
double SubtractTime(uint64_t endTime, uint64_t startTime)
|
||||
{
|
||||
uint64_t diff = endTime - startTime;
|
||||
static double conversion = 0.0;
|
||||
|
||||
if (0.0 == conversion)
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
mach_timebase_info_data_t info = { 0, 0 };
|
||||
kern_return_t err = mach_timebase_info(&info);
|
||||
if (0 == err)
|
||||
conversion = 1e-9 * (double)info.numer / (double)info.denom;
|
||||
#else
|
||||
// This function consumes output from GetTime() above, and converts the
|
||||
// time to secionds.
|
||||
#warning need accurate ticks to seconds conversion factor here. Times are invalid.
|
||||
#endif
|
||||
}
|
||||
|
||||
// strictly speaking we should also be subtracting out timer latency here
|
||||
return conversion * (double)diff;
|
||||
}
|
||||
#endif
|
||||
|
||||
void MapResultValuesComplete(const std::unique_ptr<CalcRefValsBase> &ptr);
|
||||
|
||||
void CL_CALLBACK CalcReferenceValuesComplete(cl_event e, cl_int status,
|
||||
@@ -1352,20 +1262,6 @@ cl_int PrepareReference(cl_uint job_id, cl_uint thread_id, void *p)
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
uint64_t GetTime(void)
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
return mach_absolute_time();
|
||||
#elif defined(_MSC_VER)
|
||||
return ReadTime();
|
||||
#else
|
||||
// mach_absolute_time is a high precision timer with precision < 1
|
||||
// microsecond.
|
||||
#warning need accurate clock here. Times are invalid.
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Note: not called reentrantly
|
||||
void WriteInputBufferComplete(void *data)
|
||||
{
|
||||
|
||||
@@ -86,8 +86,6 @@ extern int gSkipTesting;
|
||||
extern int gMinVectorSize;
|
||||
extern int gMaxVectorSize;
|
||||
extern int gForceFTZ;
|
||||
extern int gTimeResults;
|
||||
extern int gReportAverageTimes;
|
||||
extern int gStartTestNumber;
|
||||
extern int gEndTestNumber;
|
||||
extern int gIsRTZ;
|
||||
|
||||
@@ -226,8 +226,6 @@ static int ParseArgs(int argc, const char **argv)
|
||||
gForceFTZ ^= 1;
|
||||
gForceHalfFTZ ^= 1;
|
||||
break;
|
||||
case 't': gTimeResults ^= 1; break;
|
||||
case 'a': gReportAverageTimes ^= 1; break;
|
||||
case '1':
|
||||
if (arg[1] == '6')
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@ add_subdirectory( cl_khr_dx9_media_sharing )
|
||||
add_subdirectory( cl_khr_external_memory_dma_buf )
|
||||
add_subdirectory( cl_khr_semaphore )
|
||||
add_subdirectory( cl_khr_kernel_clock )
|
||||
add_subdirectory( cl_ext_buffer_device_address )
|
||||
if(VULKAN_IS_SUPPORTED)
|
||||
add_subdirectory( cl_khr_external_semaphore )
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
set(MODULE_NAME CL_EXT_BUFFER_DEVICE_ADDRESS)
|
||||
|
||||
set(${MODULE_NAME}_SOURCES
|
||||
main.cpp buffer_device_address.cpp
|
||||
)
|
||||
|
||||
include(../../CMakeCommon.txt)
|
||||
@@ -0,0 +1,437 @@
|
||||
// Copyright (c) 2024 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 "harness/typeWrappers.h"
|
||||
#include <cinttypes>
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
#define BUF_SIZE_STR "1024"
|
||||
|
||||
namespace {
|
||||
|
||||
static const char *program_source =
|
||||
R"raw(
|
||||
// A kernel that gets the device-seen address of the buffer.
|
||||
__kernel void get_addr (__global int *buffer,
|
||||
__global ulong* addr) {
|
||||
for (int i = 0; i < BUF_SIZE; ++i)
|
||||
buffer[i] += 1;
|
||||
*addr = (ulong)buffer;
|
||||
}
|
||||
|
||||
// A kernel that accesses another buffer indirectly.
|
||||
__kernel void indirect_access (__global long* in_addr,
|
||||
__global int* out) {
|
||||
*out = **(int __global* __global*)in_addr;
|
||||
}
|
||||
|
||||
// A kernel that gets passed a pointer to a middle of a buffer,
|
||||
// with the data _before_ the passed pointer. Tests the property
|
||||
// of sub-buffers to synchronize the whole parent buffer when
|
||||
// using the CL_MEM_BUFFER_DEVICE_ADDRESS flag.
|
||||
__kernel void ptr_arith (__global int* in_addr,
|
||||
__global int* out) {
|
||||
*out = *(in_addr - 2);
|
||||
}
|
||||
)raw";
|
||||
|
||||
class BufferDeviceAddressTest {
|
||||
|
||||
public:
|
||||
BufferDeviceAddressTest(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue,
|
||||
cl_mem_properties address_type)
|
||||
: device(device), context(context), queue(queue),
|
||||
address_type(address_type)
|
||||
{}
|
||||
|
||||
bool Skip()
|
||||
{
|
||||
cl_int error = 0;
|
||||
|
||||
cl_mem_properties buf_props[] = { address_type, CL_TRUE, 0 };
|
||||
clMemWrapper TempBuffer = clCreateBufferWithProperties(
|
||||
context, buf_props, CL_MEM_READ_WRITE,
|
||||
(size_t)BUF_SIZE * sizeof(cl_int), nullptr, &error);
|
||||
return (error != CL_SUCCESS);
|
||||
}
|
||||
|
||||
cl_int RunTest()
|
||||
{
|
||||
cl_int error;
|
||||
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper get_addr_kernel, indirect_access_kernel,
|
||||
ptr_arith_kernel;
|
||||
clMemWrapper dev_addr_buffer, buffer_long, buffer_int,
|
||||
dev_addr_no_host_buffer;
|
||||
|
||||
error = create_single_kernel_helper(context, &program, &get_addr_kernel,
|
||||
1, &program_source, "get_addr",
|
||||
"-DBUF_SIZE=" BUF_SIZE_STR);
|
||||
test_error(error, "Failed to create program with source\n");
|
||||
|
||||
indirect_access_kernel =
|
||||
clCreateKernel(program, "indirect_access", &error);
|
||||
test_error(error, "Failed to create kernel indirect_access\n");
|
||||
|
||||
ptr_arith_kernel = clCreateKernel(program, "ptr_arith", &error);
|
||||
test_error(error, "Failed to create kernel ptr_arith\n");
|
||||
|
||||
buffer_long = clCreateBuffer(context, CL_MEM_READ_WRITE,
|
||||
sizeof(cl_ulong), nullptr, &error);
|
||||
test_error(error, "clCreateBuffer failed\n");
|
||||
|
||||
buffer_int = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_int),
|
||||
nullptr, &error);
|
||||
test_error(error, "clCreateBuffer failed\n");
|
||||
|
||||
// Test a buffer with hostptr copied data
|
||||
cl_mem_properties buf_props[] = { address_type, CL_TRUE, 0 };
|
||||
dev_addr_buffer = clCreateBufferWithProperties(
|
||||
context, buf_props, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
|
||||
sizeof(cl_int) * BUF_SIZE, BufferHost, &error);
|
||||
test_error(error, "clCreateBuffer with device address 1 failed\n");
|
||||
|
||||
if (test_buffer(dev_addr_buffer, buffer_long, get_addr_kernel)
|
||||
!= TEST_PASS)
|
||||
test_fail("test_buffer_host failed\n");
|
||||
|
||||
// Test a buffer which doesn't have any hostptr associated with it.
|
||||
dev_addr_no_host_buffer = clCreateBufferWithProperties(
|
||||
context, buf_props, CL_MEM_READ_WRITE, sizeof(cl_int) * BUF_SIZE,
|
||||
nullptr, &error);
|
||||
test_error(error, "clCreateBuffer with device address 2 failed\n");
|
||||
|
||||
if (test_buffer(dev_addr_no_host_buffer, buffer_long, get_addr_kernel)
|
||||
!= TEST_PASS)
|
||||
test_fail("test_buffer_no_host failed\n");
|
||||
|
||||
// Test a buffer passed indirectly
|
||||
if (test_indirect_buffer(dev_addr_buffer, buffer_long, buffer_int,
|
||||
indirect_access_kernel)
|
||||
!= TEST_PASS)
|
||||
test_fail("test_indirect_buffer failed\n");
|
||||
|
||||
if (test_set_kernel_arg(dev_addr_buffer, buffer_int, ptr_arith_kernel)
|
||||
!= TEST_PASS)
|
||||
test_fail("test_set_kernel_arg failed\n");
|
||||
|
||||
if (test_svm_buffer() == TEST_FAIL)
|
||||
test_fail("test_svm_buffer failed\n");
|
||||
|
||||
return TEST_PASS;
|
||||
}
|
||||
|
||||
private:
|
||||
int BufferHost[BUF_SIZE];
|
||||
size_t global_size_one[3] = { 1, 1, 1 };
|
||||
cl_device_id device;
|
||||
cl_context context;
|
||||
cl_command_queue queue;
|
||||
cl_mem_properties address_type;
|
||||
|
||||
int check_device_address_from_api(cl_mem buf,
|
||||
cl_mem_device_address_ext &Addr)
|
||||
{
|
||||
Addr = 0;
|
||||
cl_int error = clGetMemObjectInfo(buf, CL_MEM_DEVICE_ADDRESS_EXT,
|
||||
sizeof(Addr), &Addr, NULL);
|
||||
test_error(error,
|
||||
"clGetMemObjectInfo(CL_MEM_DEVICE_ADDRESS_EXT) failed\n");
|
||||
if (Addr == 0)
|
||||
{
|
||||
print_error(error,
|
||||
"clGetMemObjectInfo(CL_MEM_DEVICE_ADDRESS_EXT) "
|
||||
"returned 0 as address\n");
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
int test_svm_buffer()
|
||||
{
|
||||
clSVMWrapper svm_buffer;
|
||||
clMemWrapper buffer;
|
||||
cl_int error = 0;
|
||||
|
||||
cl_device_svm_capabilities svm_caps = 0;
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_SVM_CAPABILITIES,
|
||||
sizeof(svm_caps), &svm_caps, NULL);
|
||||
if (error != CL_SUCCESS)
|
||||
{
|
||||
print_missing_feature(error,
|
||||
"Unable to get SVM capabilities, "
|
||||
"skipping");
|
||||
return TEST_SKIP;
|
||||
}
|
||||
if ((svm_caps & CL_DEVICE_SVM_COARSE_GRAIN_BUFFER) == 0)
|
||||
{
|
||||
print_missing_feature(error,
|
||||
"Device doesn't support "
|
||||
"CL_DEVICE_SVM_COARSE_"
|
||||
"GRAIN_BUFFER, skipping");
|
||||
return TEST_SKIP;
|
||||
}
|
||||
|
||||
svm_buffer =
|
||||
clSVMWrapper(context, sizeof(cl_int) * BUF_SIZE,
|
||||
CL_DEVICE_SVM_COARSE_GRAIN_BUFFER | CL_MEM_READ_WRITE);
|
||||
if (svm_buffer() == nullptr)
|
||||
{
|
||||
test_error(CL_OUT_OF_RESOURCES, "SVM allocation failed");
|
||||
}
|
||||
|
||||
cl_mem_properties buf_props[] = { address_type, CL_TRUE, 0 };
|
||||
buffer = clCreateBufferWithProperties(
|
||||
context, buf_props, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
|
||||
sizeof(cl_int) * BUF_SIZE, svm_buffer(), &error);
|
||||
test_error(error, "clCreateBuffer with device address 1 failed\n");
|
||||
|
||||
cl_mem_device_address_ext Addr = 0;
|
||||
error = clGetMemObjectInfo(buffer, CL_MEM_DEVICE_ADDRESS_EXT,
|
||||
sizeof(Addr), &Addr, NULL);
|
||||
test_error(error,
|
||||
"clGetMemObjectInfo(CL_MEM_DEVICE_ADDRESS_EXT) failed\n");
|
||||
|
||||
if ((void *)Addr != svm_buffer())
|
||||
{
|
||||
test_fail("clGetMemObjectInfo(CL_MEM_DEVICE_ADDRESS_EXT) "
|
||||
"returned different address than clSVMAlloc\n");
|
||||
}
|
||||
return TEST_PASS;
|
||||
}
|
||||
|
||||
|
||||
int test_buffer(clMemWrapper &dev_addr_buffer, clMemWrapper &plain_buffer,
|
||||
clKernelWrapper &get_addr_kernel)
|
||||
{
|
||||
cl_int error = 0;
|
||||
cl_ulong DeviceAddrFromKernel = 0;
|
||||
cl_mem_device_address_ext DeviceAddrFromAPI = 0;
|
||||
|
||||
for (int i = 0; i < BUF_SIZE; ++i)
|
||||
{
|
||||
BufferHost[i] = i;
|
||||
}
|
||||
|
||||
error =
|
||||
check_device_address_from_api(dev_addr_buffer, DeviceAddrFromAPI);
|
||||
test_error_fail(error,
|
||||
"device address buffer does not have device address");
|
||||
|
||||
error = clEnqueueWriteBuffer(queue, dev_addr_buffer,
|
||||
CL_FALSE, // block
|
||||
0, BUF_SIZE * sizeof(cl_int), BufferHost,
|
||||
0, NULL, NULL);
|
||||
test_error_fail(error,
|
||||
"clEnqueueWriteBuffer of dev_addr_buffer failed\n");
|
||||
|
||||
error = clSetKernelArg(get_addr_kernel, 0, sizeof(cl_mem),
|
||||
&dev_addr_buffer);
|
||||
test_error_fail(error, "clSetKernelArg 0 failed\n");
|
||||
error =
|
||||
clSetKernelArg(get_addr_kernel, 1, sizeof(cl_mem), &plain_buffer);
|
||||
test_error_fail(error, "clSetKernelArg 1 failed\n");
|
||||
|
||||
error = clEnqueueNDRangeKernel(queue, get_addr_kernel, 1, NULL,
|
||||
global_size_one, NULL, 0, NULL, NULL);
|
||||
test_error_fail(error, "clNDRangeKernel failed\n");
|
||||
|
||||
error = clEnqueueReadBuffer(queue, dev_addr_buffer, CL_FALSE, 0,
|
||||
sizeof(cl_int) * BUF_SIZE, BufferHost, 0,
|
||||
NULL, NULL);
|
||||
test_error_fail(error,
|
||||
"clEnqueueReadBuffer of dev_addr_buffer failed\n");
|
||||
|
||||
error = clEnqueueReadBuffer(queue, plain_buffer, CL_FALSE, 0,
|
||||
sizeof(cl_ulong), &DeviceAddrFromKernel, 0,
|
||||
NULL, NULL);
|
||||
test_error_fail(error, "clEnqueueReadBuffer of buffer failed\n");
|
||||
|
||||
error = clFinish(queue);
|
||||
test_error_fail(error, "clFinish failed\n");
|
||||
|
||||
for (int i = 0; i < BUF_SIZE; ++i)
|
||||
{
|
||||
if (BufferHost[i] != (i + 1))
|
||||
{
|
||||
test_fail("BufferHost[%i] expected "
|
||||
"to be: %i, but is: %i\n",
|
||||
i, i + 1, BufferHost[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (DeviceAddrFromAPI != DeviceAddrFromKernel)
|
||||
{
|
||||
test_fail("DeviceAddrFromAPI(%" PRIu64
|
||||
") != DeviceAddrFromKernel(%" PRIu64 ")\n",
|
||||
(uint64_t)DeviceAddrFromAPI,
|
||||
(uint64_t)DeviceAddrFromKernel);
|
||||
}
|
||||
return TEST_PASS;
|
||||
}
|
||||
|
||||
int test_indirect_buffer(clMemWrapper &dev_addr_buffer,
|
||||
clMemWrapper &buffer_in_long,
|
||||
clMemWrapper &buffer_out_int,
|
||||
clKernelWrapper &ind_access_kernel)
|
||||
{
|
||||
cl_int error = 0;
|
||||
cl_mem_device_address_ext DeviceAddrFromAPI = 0;
|
||||
|
||||
int DataIn = 0x12348765;
|
||||
int DataOut = -1;
|
||||
|
||||
// A devaddr buffer with the payload data.
|
||||
error = clEnqueueWriteBuffer(queue, dev_addr_buffer,
|
||||
CL_TRUE, // block
|
||||
0, sizeof(cl_int), &DataIn, 0, NULL, NULL);
|
||||
test_error_fail(error,
|
||||
"clEnqueueWriteBuffer of dev_addr_buffer failed\n");
|
||||
|
||||
error =
|
||||
check_device_address_from_api(dev_addr_buffer, DeviceAddrFromAPI);
|
||||
test_error_fail(error,
|
||||
"device address buffer does not have device address")
|
||||
|
||||
// A basic buffer used to pass the other buffer's address.
|
||||
error = clEnqueueWriteBuffer(queue, buffer_in_long,
|
||||
CL_TRUE, // block
|
||||
0, sizeof(cl_long), &DeviceAddrFromAPI,
|
||||
0, NULL, NULL);
|
||||
test_error_fail(error,
|
||||
"clEnqueueWriteBuffer of dev_addr_buffer failed\n");
|
||||
|
||||
error = clSetKernelArg(ind_access_kernel, 0, sizeof(cl_mem),
|
||||
&buffer_in_long);
|
||||
test_error_fail(error, "clSetKernelArg 0 failed\n");
|
||||
error = clSetKernelArg(ind_access_kernel, 1, sizeof(cl_mem),
|
||||
&buffer_out_int);
|
||||
test_error_fail(error, "clSetKernelArg 1 failed\n");
|
||||
|
||||
error = clSetKernelExecInfo(ind_access_kernel,
|
||||
CL_KERNEL_EXEC_INFO_DEVICE_PTRS_EXT,
|
||||
sizeof(void *), &DeviceAddrFromAPI);
|
||||
test_error_fail(error,
|
||||
"Setting indirect access for "
|
||||
"device ptrs failed!\n");
|
||||
|
||||
error = clEnqueueNDRangeKernel(queue, ind_access_kernel, 1, NULL,
|
||||
global_size_one, NULL, 0, NULL, NULL);
|
||||
test_error_fail(error, "clNDRangeKernel failed\n");
|
||||
|
||||
error = clEnqueueReadBuffer(queue, buffer_out_int, CL_FALSE, 0,
|
||||
sizeof(cl_int), &DataOut, 0, NULL, NULL);
|
||||
test_error_fail(error, "clEnqueueReadBuffer of buffer failed\n");
|
||||
|
||||
error = clFinish(queue);
|
||||
test_error_fail(error, "clFinish failed\n");
|
||||
|
||||
for (int i = 0; i < BUF_SIZE; ++i)
|
||||
{
|
||||
if (BufferHost[i] != i + 1)
|
||||
{
|
||||
test_fail("PinnedBufferHost[%i] expected "
|
||||
"to be: %i, but is: %i\n",
|
||||
i, i + 1, BufferHost[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (DataIn != DataOut)
|
||||
{
|
||||
test_fail("Passing data via indirect buffers failed. "
|
||||
"Got: %i expected: %i\n",
|
||||
DataOut, DataIn);
|
||||
}
|
||||
return TEST_PASS;
|
||||
}
|
||||
|
||||
int test_set_kernel_arg(clMemWrapper &dev_addr_buffer,
|
||||
clMemWrapper &buffer_out_int,
|
||||
clKernelWrapper &ptr_arith_kernel)
|
||||
{
|
||||
cl_int error = 0;
|
||||
cl_mem_device_address_ext DeviceAddrFromAPI = 0;
|
||||
int DataOut = -1;
|
||||
int DataIn = 0x12348765;
|
||||
|
||||
clSetKernelArgDevicePointerEXT_fn clSetKernelArgDevicePointer =
|
||||
(clSetKernelArgDevicePointerEXT_fn)
|
||||
clGetExtensionFunctionAddressForPlatform(
|
||||
getPlatformFromDevice(device),
|
||||
"clSetKernelArgDevicePointerEXT");
|
||||
if (clSetKernelArgDevicePointer == nullptr)
|
||||
test_error_fail(
|
||||
error, "Cannot get address of clSetKernelArgDevicePointerEXT");
|
||||
|
||||
error = clEnqueueWriteBuffer(queue, dev_addr_buffer,
|
||||
CL_FALSE, // block
|
||||
0, sizeof(cl_int), &DataIn, 0, NULL, NULL);
|
||||
test_error_fail(error,
|
||||
"clEnqueueWriteBuffer of dev_addr_buffer failed\n");
|
||||
|
||||
error =
|
||||
check_device_address_from_api(dev_addr_buffer, DeviceAddrFromAPI);
|
||||
test_error_fail(error, "dev_addr_buffer does not have device address");
|
||||
|
||||
cl_mem_device_address_ext DeviceAddrFromAPIP2 =
|
||||
(cl_mem_device_address_ext)(((cl_uint *)DeviceAddrFromAPI) + 2);
|
||||
error = clSetKernelArgDevicePointer(ptr_arith_kernel, 0,
|
||||
DeviceAddrFromAPIP2);
|
||||
test_error_fail(error, "clSetKernelArgDevicePointer failed\n");
|
||||
error = clSetKernelArg(ptr_arith_kernel, 1, sizeof(cl_mem),
|
||||
&buffer_out_int);
|
||||
test_error_fail(error, "clSetKernelArg 1 failed\n");
|
||||
|
||||
error = clEnqueueNDRangeKernel(queue, ptr_arith_kernel, 1, NULL,
|
||||
global_size_one, NULL, 0, NULL, NULL);
|
||||
test_error_fail(error, "clNDRangeKernel failed\n");
|
||||
|
||||
error = clEnqueueReadBuffer(queue, buffer_out_int, CL_FALSE, 0,
|
||||
sizeof(cl_int), &DataOut, 0, NULL, NULL);
|
||||
test_error_fail(error, "clEnqueueReadBuffer of buffer failed\n");
|
||||
|
||||
error = clFinish(queue);
|
||||
test_error_fail(error, "clFinish failed\n");
|
||||
|
||||
if (DataIn != DataOut)
|
||||
{
|
||||
test_fail("Negative offsetting from passed in pointer failed: "
|
||||
"got: %i expected: %i",
|
||||
DataOut, DataIn);
|
||||
}
|
||||
return TEST_PASS;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
REGISTER_TEST(private_address)
|
||||
{
|
||||
BufferDeviceAddressTest test_fixture = BufferDeviceAddressTest(
|
||||
device, context, queue, CL_MEM_DEVICE_PRIVATE_ADDRESS_EXT);
|
||||
|
||||
if (test_fixture.Skip())
|
||||
{
|
||||
log_info("Test fixture skip\n");
|
||||
return TEST_SKIPPED_ITSELF;
|
||||
}
|
||||
|
||||
cl_int error = test_fixture.RunTest();
|
||||
test_error_ret(error, "Test Failed", TEST_FAIL);
|
||||
|
||||
return TEST_PASS;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// Copyright (c) 2024 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 "harness/testHarness.h"
|
||||
#include "harness/deviceInfo.h"
|
||||
|
||||
test_status InitCL(cl_device_id device)
|
||||
{
|
||||
auto version = get_device_cl_version(device);
|
||||
auto expected_min_version = Version(3, 0);
|
||||
|
||||
if (version < expected_min_version)
|
||||
{
|
||||
version_expected_info("Test", "OpenCL",
|
||||
expected_min_version.to_string().c_str(),
|
||||
version.to_string().c_str());
|
||||
return TEST_SKIP;
|
||||
}
|
||||
|
||||
if (!is_extension_available(device, "cl_ext_buffer_device_address"))
|
||||
{
|
||||
log_info("The device does not support the "
|
||||
"cl_ext_buffer_device_address extension.\n");
|
||||
return TEST_SKIPPED_ITSELF;
|
||||
}
|
||||
|
||||
cl_version ext_version =
|
||||
get_extension_version(device, "cl_ext_buffer_device_address");
|
||||
if (ext_version != CL_MAKE_VERSION(1, 0, 2))
|
||||
{
|
||||
log_info("The test is written against cl_ext_buffer_device_address "
|
||||
"extension version 1.0.2, device supports version: %u.%u.%u\n",
|
||||
CL_VERSION_MAJOR(ext_version), CL_VERSION_MINOR(ext_version),
|
||||
CL_VERSION_PATCH(ext_version));
|
||||
return TEST_SKIPPED_ITSELF;
|
||||
}
|
||||
|
||||
return TEST_PASS;
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
return runTestHarnessWithCheck(
|
||||
argc, argv, test_registry::getInstance().num_tests(),
|
||||
test_registry::getInstance().definitions(), false, 0, InitCL);
|
||||
}
|
||||
@@ -13,8 +13,9 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "procs.h"
|
||||
#include <CL/cl.h>
|
||||
|
||||
#include "harness/typeWrappers.h"
|
||||
|
||||
int test_cxx_for_opencl(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue)
|
||||
@@ -90,8 +91,7 @@ int test_cxx_for_opencl(cl_device_id device, cl_context context,
|
||||
return TEST_PASS;
|
||||
}
|
||||
|
||||
int test_cxx_for_opencl_ext(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int)
|
||||
REGISTER_TEST_VERSION(cxx_for_opencl_ext, Version(2, 0))
|
||||
{
|
||||
if (!is_extension_available(device, "cl_ext_cxx_for_opencl"))
|
||||
{
|
||||
|
||||
@@ -13,8 +13,9 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "procs.h"
|
||||
#include <CL/cl.h>
|
||||
|
||||
#include "harness/typeWrappers.h"
|
||||
|
||||
int test_cxx_for_opencl_version(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue)
|
||||
@@ -88,8 +89,7 @@ int test_cxx_for_opencl_version(cl_device_id device, cl_context context,
|
||||
return TEST_PASS;
|
||||
}
|
||||
|
||||
int test_cxx_for_opencl_ver(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int)
|
||||
REGISTER_TEST_VERSION(cxx_for_opencl_ver, Version(2, 0))
|
||||
{
|
||||
if (!is_extension_available(device, "cl_ext_cxx_for_opencl"))
|
||||
{
|
||||
|
||||
@@ -14,15 +14,11 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
#include "procs.h"
|
||||
|
||||
test_definition test_list[] = {
|
||||
ADD_TEST_VERSION(cxx_for_opencl_ext, Version(2, 0)),
|
||||
ADD_TEST_VERSION(cxx_for_opencl_ver, Version(2, 0))
|
||||
};
|
||||
#include "harness/testHarness.h"
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
return runTestHarnessWithCheck(argc, argv, ARRAY_SIZE(test_list), test_list,
|
||||
false, 0, nullptr);
|
||||
return runTestHarnessWithCheck(
|
||||
argc, argv, test_registry::getInstance().num_tests(),
|
||||
test_registry::getInstance().definitions(), false, 0, nullptr);
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2021 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.
|
||||
//
|
||||
#ifndef _procs_h
|
||||
#define _procs_h
|
||||
|
||||
#include "harness/typeWrappers.h"
|
||||
|
||||
extern int test_cxx_for_opencl_ext(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int);
|
||||
extern int test_cxx_for_opencl_ver(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int);
|
||||
|
||||
#endif /*_procs_h*/
|
||||
@@ -3,6 +3,7 @@ set(MODULE_NAME CL_KHR_COMMAND_BUFFER)
|
||||
set(${MODULE_NAME}_SOURCES
|
||||
main.cpp
|
||||
basic_command_buffer.cpp
|
||||
basic_command_buffer_tests.cpp
|
||||
svm_command_basic.cpp
|
||||
command_buffer_printf.cpp
|
||||
command_buffer_get_command_buffer_info.cpp
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "basic_command_buffer.h"
|
||||
#include "procs.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
@@ -186,324 +185,253 @@ cl_int BasicCommandBufferTest::SetUp(int elements)
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Test that the CL_COMMAND_BUFFER_FLAGS_KHR bitfield is parsed correctly when
|
||||
// multiple flags are set.
|
||||
struct MultiFlagCreationTest : public BasicCommandBufferTest
|
||||
cl_int MultiFlagCreationTest::Run()
|
||||
{
|
||||
using BasicCommandBufferTest::BasicCommandBufferTest;
|
||||
cl_command_buffer_properties_khr flags = 0;
|
||||
cl_int error = CL_SUCCESS;
|
||||
|
||||
cl_int Run() override
|
||||
// First try to find multiple flags that are supported by the driver and
|
||||
// device.
|
||||
if (simultaneous_use_support)
|
||||
{
|
||||
cl_command_buffer_properties_khr flags = 0;
|
||||
cl_int error = CL_SUCCESS;
|
||||
|
||||
// First try to find multiple flags that are supported by the driver and
|
||||
// device.
|
||||
if (simultaneous_use_support)
|
||||
{
|
||||
flags |= CL_COMMAND_BUFFER_SIMULTANEOUS_USE_KHR;
|
||||
}
|
||||
|
||||
if (is_extension_available(
|
||||
device, CL_KHR_COMMAND_BUFFER_MULTI_DEVICE_EXTENSION_NAME))
|
||||
{
|
||||
flags |= CL_COMMAND_BUFFER_DEVICE_SIDE_SYNC_KHR;
|
||||
}
|
||||
|
||||
if (is_extension_available(
|
||||
device, CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_EXTENSION_NAME))
|
||||
{
|
||||
flags |= CL_COMMAND_BUFFER_MUTABLE_KHR;
|
||||
}
|
||||
|
||||
cl_command_buffer_properties_khr props[] = {
|
||||
CL_COMMAND_BUFFER_FLAGS_KHR, flags, 0
|
||||
};
|
||||
|
||||
command_buffer = clCreateCommandBufferKHR(1, &queue, props, &error);
|
||||
test_error(error, "clCreateCommandBufferKHR failed");
|
||||
|
||||
return CL_SUCCESS;
|
||||
flags |= CL_COMMAND_BUFFER_SIMULTANEOUS_USE_KHR;
|
||||
}
|
||||
|
||||
if (is_extension_available(
|
||||
device, CL_KHR_COMMAND_BUFFER_MULTI_DEVICE_EXTENSION_NAME))
|
||||
{
|
||||
flags |= CL_COMMAND_BUFFER_DEVICE_SIDE_SYNC_KHR;
|
||||
}
|
||||
|
||||
if (is_extension_available(
|
||||
device, CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_EXTENSION_NAME))
|
||||
{
|
||||
flags |= CL_COMMAND_BUFFER_MUTABLE_KHR;
|
||||
}
|
||||
|
||||
cl_command_buffer_properties_khr props[] = { CL_COMMAND_BUFFER_FLAGS_KHR,
|
||||
flags, 0 };
|
||||
|
||||
command_buffer = clCreateCommandBufferKHR(1, &queue, props, &error);
|
||||
test_error(error, "clCreateCommandBufferKHR failed");
|
||||
|
||||
return CL_SUCCESS;
|
||||
};
|
||||
|
||||
// Test enqueuing a command-buffer containing a single NDRange command once
|
||||
struct BasicEnqueueTest : public BasicCommandBufferTest
|
||||
cl_int BasicEnqueueTest::Run()
|
||||
{
|
||||
using BasicCommandBufferTest::BasicCommandBufferTest;
|
||||
|
||||
cl_int Run() override
|
||||
cl_int error = clCommandNDRangeKernelKHR(
|
||||
command_buffer, nullptr, nullptr, kernel, 1, nullptr, &num_elements,
|
||||
nullptr, 0, nullptr, nullptr, nullptr);
|
||||
test_error(error, "clCommandNDRangeKernelKHR failed");
|
||||
|
||||
error = clFinalizeCommandBufferKHR(command_buffer);
|
||||
test_error(error, "clFinalizeCommandBufferKHR failed");
|
||||
|
||||
const cl_int pattern = 42;
|
||||
error = clEnqueueFillBuffer(queue, in_mem, &pattern, sizeof(cl_int), 0,
|
||||
data_size(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueFillBuffer failed");
|
||||
|
||||
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, nullptr,
|
||||
nullptr);
|
||||
test_error(error, "clEnqueueCommandBufferKHR failed");
|
||||
|
||||
std::vector<cl_int> output_data_1(num_elements);
|
||||
error = clEnqueueReadBuffer(queue, out_mem, CL_TRUE, 0, data_size(),
|
||||
output_data_1.data(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
for (size_t i = 0; i < num_elements; i++)
|
||||
{
|
||||
cl_int error = clCommandNDRangeKernelKHR(
|
||||
CHECK_VERIFICATION_ERROR(pattern, output_data_1[i], i);
|
||||
}
|
||||
|
||||
const cl_int new_pattern = 12;
|
||||
error = clEnqueueFillBuffer(queue, in_mem, &new_pattern, sizeof(cl_int), 0,
|
||||
data_size(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueFillBuffer failed");
|
||||
|
||||
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, nullptr,
|
||||
nullptr);
|
||||
test_error(error, "clEnqueueCommandBufferKHR failed");
|
||||
|
||||
std::vector<cl_int> output_data_2(num_elements);
|
||||
error = clEnqueueReadBuffer(queue, out_mem, CL_TRUE, 0, data_size(),
|
||||
output_data_2.data(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
for (size_t i = 0; i < num_elements; i++)
|
||||
{
|
||||
CHECK_VERIFICATION_ERROR(new_pattern, output_data_2[i], i);
|
||||
}
|
||||
|
||||
return CL_SUCCESS;
|
||||
};
|
||||
|
||||
cl_int MixedCommandsTest::Run()
|
||||
{
|
||||
cl_int error;
|
||||
const size_t iterations = 4;
|
||||
clMemWrapper result_mem =
|
||||
clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_int) * iterations,
|
||||
nullptr, &error);
|
||||
test_error(error, "clCreateBuffer failed");
|
||||
|
||||
const cl_int pattern_base = 42;
|
||||
for (size_t i = 0; i < iterations; i++)
|
||||
{
|
||||
const cl_int pattern = pattern_base + i;
|
||||
cl_int error = clCommandFillBufferKHR(
|
||||
command_buffer, nullptr, nullptr, in_mem, &pattern, sizeof(cl_int),
|
||||
0, data_size(), 0, nullptr, nullptr, nullptr);
|
||||
test_error(error, "clCommandFillBufferKHR failed");
|
||||
|
||||
error = clCommandNDRangeKernelKHR(
|
||||
command_buffer, nullptr, nullptr, kernel, 1, nullptr, &num_elements,
|
||||
nullptr, 0, nullptr, nullptr, nullptr);
|
||||
test_error(error, "clCommandNDRangeKernelKHR failed");
|
||||
|
||||
error = clFinalizeCommandBufferKHR(command_buffer);
|
||||
test_error(error, "clFinalizeCommandBufferKHR failed");
|
||||
|
||||
const cl_int pattern = 42;
|
||||
error = clEnqueueFillBuffer(queue, in_mem, &pattern, sizeof(cl_int), 0,
|
||||
data_size(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueFillBuffer failed");
|
||||
|
||||
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0,
|
||||
nullptr, nullptr);
|
||||
test_error(error, "clEnqueueCommandBufferKHR failed");
|
||||
|
||||
std::vector<cl_int> output_data_1(num_elements);
|
||||
error = clEnqueueReadBuffer(queue, out_mem, CL_TRUE, 0, data_size(),
|
||||
output_data_1.data(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
for (size_t i = 0; i < num_elements; i++)
|
||||
{
|
||||
CHECK_VERIFICATION_ERROR(pattern, output_data_1[i], i);
|
||||
}
|
||||
|
||||
const cl_int new_pattern = 12;
|
||||
error = clEnqueueFillBuffer(queue, in_mem, &new_pattern, sizeof(cl_int),
|
||||
0, data_size(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueFillBuffer failed");
|
||||
|
||||
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0,
|
||||
nullptr, nullptr);
|
||||
test_error(error, "clEnqueueCommandBufferKHR failed");
|
||||
|
||||
std::vector<cl_int> output_data_2(num_elements);
|
||||
error = clEnqueueReadBuffer(queue, out_mem, CL_TRUE, 0, data_size(),
|
||||
output_data_2.data(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
for (size_t i = 0; i < num_elements; i++)
|
||||
{
|
||||
CHECK_VERIFICATION_ERROR(new_pattern, output_data_2[i], i);
|
||||
}
|
||||
|
||||
return CL_SUCCESS;
|
||||
const size_t result_offset = i * sizeof(cl_int);
|
||||
error = clCommandCopyBufferKHR(
|
||||
command_buffer, nullptr, nullptr, out_mem, result_mem, 0,
|
||||
result_offset, sizeof(cl_int), 0, nullptr, nullptr, nullptr);
|
||||
test_error(error, "clCommandCopyBufferKHR failed");
|
||||
}
|
||||
};
|
||||
|
||||
// Test enqueuing a command-buffer containing multiple command, including
|
||||
// operations other than NDRange kernel execution.
|
||||
struct MixedCommandsTest : public BasicCommandBufferTest
|
||||
{
|
||||
using BasicCommandBufferTest::BasicCommandBufferTest;
|
||||
error = clFinalizeCommandBufferKHR(command_buffer);
|
||||
test_error(error, "clFinalizeCommandBufferKHR failed");
|
||||
|
||||
cl_int Run() override
|
||||
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, nullptr,
|
||||
nullptr);
|
||||
test_error(error, "clEnqueueCommandBufferKHR failed");
|
||||
|
||||
std::vector<cl_int> result_data(num_elements);
|
||||
error = clEnqueueReadBuffer(queue, result_mem, CL_TRUE, 0,
|
||||
iterations * sizeof(cl_int), result_data.data(),
|
||||
0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
for (size_t i = 0; i < iterations; i++)
|
||||
{
|
||||
cl_int error;
|
||||
const size_t iterations = 4;
|
||||
clMemWrapper result_mem =
|
||||
clCreateBuffer(context, CL_MEM_READ_WRITE,
|
||||
sizeof(cl_int) * iterations, nullptr, &error);
|
||||
test_error(error, "clCreateBuffer failed");
|
||||
|
||||
const cl_int pattern_base = 42;
|
||||
for (size_t i = 0; i < iterations; i++)
|
||||
{
|
||||
const cl_int pattern = pattern_base + i;
|
||||
cl_int error = clCommandFillBufferKHR(
|
||||
command_buffer, nullptr, nullptr, in_mem, &pattern,
|
||||
sizeof(cl_int), 0, data_size(), 0, nullptr, nullptr, nullptr);
|
||||
test_error(error, "clCommandFillBufferKHR failed");
|
||||
|
||||
error = clCommandNDRangeKernelKHR(
|
||||
command_buffer, nullptr, nullptr, kernel, 1, nullptr,
|
||||
&num_elements, nullptr, 0, nullptr, nullptr, nullptr);
|
||||
test_error(error, "clCommandNDRangeKernelKHR failed");
|
||||
|
||||
const size_t result_offset = i * sizeof(cl_int);
|
||||
error = clCommandCopyBufferKHR(
|
||||
command_buffer, nullptr, nullptr, out_mem, result_mem, 0,
|
||||
result_offset, sizeof(cl_int), 0, nullptr, nullptr, nullptr);
|
||||
test_error(error, "clCommandCopyBufferKHR failed");
|
||||
}
|
||||
|
||||
error = clFinalizeCommandBufferKHR(command_buffer);
|
||||
test_error(error, "clFinalizeCommandBufferKHR failed");
|
||||
|
||||
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0,
|
||||
nullptr, nullptr);
|
||||
test_error(error, "clEnqueueCommandBufferKHR failed");
|
||||
|
||||
std::vector<cl_int> result_data(num_elements);
|
||||
error = clEnqueueReadBuffer(queue, result_mem, CL_TRUE, 0,
|
||||
iterations * sizeof(cl_int),
|
||||
result_data.data(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
for (size_t i = 0; i < iterations; i++)
|
||||
{
|
||||
const cl_int ref = pattern_base + i;
|
||||
CHECK_VERIFICATION_ERROR(ref, result_data[i], i);
|
||||
}
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
};
|
||||
|
||||
// Test flushing the command-queue between command-buffer enqueues
|
||||
struct ExplicitFlushTest : public BasicCommandBufferTest
|
||||
{
|
||||
using BasicCommandBufferTest::BasicCommandBufferTest;
|
||||
|
||||
cl_int Run() override
|
||||
{
|
||||
cl_int error = clCommandNDRangeKernelKHR(
|
||||
command_buffer, nullptr, nullptr, kernel, 1, nullptr, &num_elements,
|
||||
nullptr, 0, nullptr, nullptr, nullptr);
|
||||
test_error(error, "clCommandNDRangeKernelKHR failed");
|
||||
|
||||
error = clFinalizeCommandBufferKHR(command_buffer);
|
||||
test_error(error, "clFinalizeCommandBufferKHR failed");
|
||||
|
||||
const cl_int pattern_A = 42;
|
||||
error = clEnqueueFillBuffer(queue, in_mem, &pattern_A, sizeof(cl_int),
|
||||
0, data_size(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueFillBuffer failed");
|
||||
|
||||
error = clFlush(queue);
|
||||
test_error(error, "clFlush failed");
|
||||
|
||||
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0,
|
||||
nullptr, nullptr);
|
||||
test_error(error, "clEnqueueCommandBufferKHR failed");
|
||||
|
||||
std::vector<cl_int> output_data_A(num_elements);
|
||||
error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
|
||||
output_data_A.data(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
const cl_int pattern_B = 0xA;
|
||||
error = clEnqueueFillBuffer(queue, in_mem, &pattern_B, sizeof(cl_int),
|
||||
0, data_size(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueFillBuffer failed");
|
||||
|
||||
error = clFlush(queue);
|
||||
test_error(error, "clFlush failed");
|
||||
|
||||
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0,
|
||||
nullptr, nullptr);
|
||||
test_error(error, "clEnqueueCommandBufferKHR failed");
|
||||
|
||||
error = clFlush(queue);
|
||||
test_error(error, "clFlush failed");
|
||||
|
||||
std::vector<cl_int> output_data_B(num_elements);
|
||||
error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
|
||||
output_data_B.data(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
error = clFinish(queue);
|
||||
test_error(error, "clFinish failed");
|
||||
|
||||
for (size_t i = 0; i < num_elements; i++)
|
||||
{
|
||||
CHECK_VERIFICATION_ERROR(pattern_A, output_data_A[i], i);
|
||||
|
||||
CHECK_VERIFICATION_ERROR(pattern_B, output_data_B[i], i);
|
||||
}
|
||||
return CL_SUCCESS;
|
||||
const cl_int ref = pattern_base + i;
|
||||
CHECK_VERIFICATION_ERROR(ref, result_data[i], i);
|
||||
}
|
||||
|
||||
bool Skip() override
|
||||
{
|
||||
return BasicCommandBufferTest::Skip() || !simultaneous_use_support;
|
||||
}
|
||||
};
|
||||
|
||||
// Test enqueueing a command-buffer twice separated by another enqueue operation
|
||||
struct InterleavedEnqueueTest : public BasicCommandBufferTest
|
||||
{
|
||||
using BasicCommandBufferTest::BasicCommandBufferTest;
|
||||
|
||||
cl_int Run() override
|
||||
{
|
||||
cl_int error = clCommandNDRangeKernelKHR(
|
||||
command_buffer, nullptr, nullptr, kernel, 1, nullptr, &num_elements,
|
||||
nullptr, 0, nullptr, nullptr, nullptr);
|
||||
test_error(error, "clCommandNDRangeKernelKHR failed");
|
||||
|
||||
error = clFinalizeCommandBufferKHR(command_buffer);
|
||||
test_error(error, "clFinalizeCommandBufferKHR failed");
|
||||
|
||||
cl_int pattern = 42;
|
||||
error = clEnqueueFillBuffer(queue, in_mem, &pattern, sizeof(cl_int), 0,
|
||||
data_size(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueFillBuffer failed");
|
||||
|
||||
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0,
|
||||
nullptr, nullptr);
|
||||
test_error(error, "clEnqueueCommandBufferKHR failed");
|
||||
|
||||
pattern = 0xABCD;
|
||||
error = clEnqueueFillBuffer(queue, in_mem, &pattern, sizeof(cl_int), 0,
|
||||
data_size(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueFillBuffer failed");
|
||||
|
||||
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0,
|
||||
nullptr, nullptr);
|
||||
test_error(error, "clEnqueueCommandBufferKHR failed");
|
||||
|
||||
error = clEnqueueCopyBuffer(queue, in_mem, out_mem, 0, 0, data_size(),
|
||||
0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueCopyBuffer failed");
|
||||
|
||||
std::vector<cl_int> output_data(num_elements);
|
||||
error = clEnqueueReadBuffer(queue, out_mem, CL_TRUE, 0, data_size(),
|
||||
output_data.data(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
for (size_t i = 0; i < num_elements; i++)
|
||||
{
|
||||
CHECK_VERIFICATION_ERROR(pattern, output_data[i], i);
|
||||
}
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
bool Skip() override
|
||||
{
|
||||
return BasicCommandBufferTest::Skip() || !simultaneous_use_support;
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int test_multi_flag_creation(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
{
|
||||
return MakeAndRunTest<MultiFlagCreationTest>(device, context, queue,
|
||||
num_elements);
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
int test_single_ndrange(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
cl_int ExplicitFlushTest::Run()
|
||||
{
|
||||
return MakeAndRunTest<BasicEnqueueTest>(device, context, queue,
|
||||
num_elements);
|
||||
cl_int error = clCommandNDRangeKernelKHR(
|
||||
command_buffer, nullptr, nullptr, kernel, 1, nullptr, &num_elements,
|
||||
nullptr, 0, nullptr, nullptr, nullptr);
|
||||
test_error(error, "clCommandNDRangeKernelKHR failed");
|
||||
|
||||
error = clFinalizeCommandBufferKHR(command_buffer);
|
||||
test_error(error, "clFinalizeCommandBufferKHR failed");
|
||||
|
||||
const cl_int pattern_A = 42;
|
||||
error = clEnqueueFillBuffer(queue, in_mem, &pattern_A, sizeof(cl_int), 0,
|
||||
data_size(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueFillBuffer failed");
|
||||
|
||||
error = clFlush(queue);
|
||||
test_error(error, "clFlush failed");
|
||||
|
||||
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, nullptr,
|
||||
nullptr);
|
||||
test_error(error, "clEnqueueCommandBufferKHR failed");
|
||||
|
||||
std::vector<cl_int> output_data_A(num_elements);
|
||||
error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
|
||||
output_data_A.data(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
const cl_int pattern_B = 0xA;
|
||||
error = clEnqueueFillBuffer(queue, in_mem, &pattern_B, sizeof(cl_int), 0,
|
||||
data_size(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueFillBuffer failed");
|
||||
|
||||
error = clFlush(queue);
|
||||
test_error(error, "clFlush failed");
|
||||
|
||||
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, nullptr,
|
||||
nullptr);
|
||||
test_error(error, "clEnqueueCommandBufferKHR failed");
|
||||
|
||||
error = clFlush(queue);
|
||||
test_error(error, "clFlush failed");
|
||||
|
||||
std::vector<cl_int> output_data_B(num_elements);
|
||||
error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
|
||||
output_data_B.data(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
error = clFinish(queue);
|
||||
test_error(error, "clFinish failed");
|
||||
|
||||
for (size_t i = 0; i < num_elements; i++)
|
||||
{
|
||||
CHECK_VERIFICATION_ERROR(pattern_A, output_data_A[i], i);
|
||||
|
||||
CHECK_VERIFICATION_ERROR(pattern_B, output_data_B[i], i);
|
||||
}
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
int test_interleaved_enqueue(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
bool ExplicitFlushTest::Skip()
|
||||
{
|
||||
return MakeAndRunTest<InterleavedEnqueueTest>(device, context, queue,
|
||||
num_elements);
|
||||
return BasicCommandBufferTest::Skip() || !simultaneous_use_support;
|
||||
}
|
||||
|
||||
int test_mixed_commands(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
cl_int InterleavedEnqueueTest::Run()
|
||||
{
|
||||
return MakeAndRunTest<MixedCommandsTest>(device, context, queue,
|
||||
num_elements);
|
||||
cl_int error = clCommandNDRangeKernelKHR(
|
||||
command_buffer, nullptr, nullptr, kernel, 1, nullptr, &num_elements,
|
||||
nullptr, 0, nullptr, nullptr, nullptr);
|
||||
test_error(error, "clCommandNDRangeKernelKHR failed");
|
||||
|
||||
error = clFinalizeCommandBufferKHR(command_buffer);
|
||||
test_error(error, "clFinalizeCommandBufferKHR failed");
|
||||
|
||||
cl_int pattern = 42;
|
||||
error = clEnqueueFillBuffer(queue, in_mem, &pattern, sizeof(cl_int), 0,
|
||||
data_size(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueFillBuffer failed");
|
||||
|
||||
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, nullptr,
|
||||
nullptr);
|
||||
test_error(error, "clEnqueueCommandBufferKHR failed");
|
||||
|
||||
pattern = 0xABCD;
|
||||
error = clEnqueueFillBuffer(queue, in_mem, &pattern, sizeof(cl_int), 0,
|
||||
data_size(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueFillBuffer failed");
|
||||
|
||||
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, nullptr,
|
||||
nullptr);
|
||||
test_error(error, "clEnqueueCommandBufferKHR failed");
|
||||
|
||||
error = clEnqueueCopyBuffer(queue, in_mem, out_mem, 0, 0, data_size(), 0,
|
||||
nullptr, nullptr);
|
||||
test_error(error, "clEnqueueCopyBuffer failed");
|
||||
|
||||
std::vector<cl_int> output_data(num_elements);
|
||||
error = clEnqueueReadBuffer(queue, out_mem, CL_TRUE, 0, data_size(),
|
||||
output_data.data(), 0, nullptr, nullptr);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
for (size_t i = 0; i < num_elements; i++)
|
||||
{
|
||||
CHECK_VERIFICATION_ERROR(pattern, output_data[i], i);
|
||||
}
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
int test_explicit_flush(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
bool InterleavedEnqueueTest::Skip()
|
||||
{
|
||||
return MakeAndRunTest<ExplicitFlushTest>(device, context, queue,
|
||||
num_elements);
|
||||
return BasicCommandBufferTest::Skip() || !simultaneous_use_support;
|
||||
}
|
||||
|
||||
@@ -84,6 +84,49 @@ protected:
|
||||
clCommandBufferWrapper command_buffer;
|
||||
};
|
||||
|
||||
// Test that CL_COMMAND_BUFFER_FLAGS_KHR bitfield is parsed correctly when
|
||||
// multiple flags are set.
|
||||
struct MultiFlagCreationTest : public BasicCommandBufferTest
|
||||
{
|
||||
using BasicCommandBufferTest::BasicCommandBufferTest;
|
||||
|
||||
cl_int Run() override;
|
||||
};
|
||||
|
||||
// Test enqueuing a command-buffer containing a single NDRange command once
|
||||
struct BasicEnqueueTest : public BasicCommandBufferTest
|
||||
{
|
||||
using BasicCommandBufferTest::BasicCommandBufferTest;
|
||||
|
||||
cl_int Run() override;
|
||||
};
|
||||
|
||||
// Test enqueuing a command-buffer containing multiple command, including
|
||||
// operations other than NDRange kernel execution.
|
||||
struct MixedCommandsTest : public BasicCommandBufferTest
|
||||
{
|
||||
using BasicCommandBufferTest::BasicCommandBufferTest;
|
||||
|
||||
cl_int Run() override;
|
||||
};
|
||||
|
||||
// Test flushing the command-queue between command-buffer enqueues
|
||||
struct ExplicitFlushTest : public BasicCommandBufferTest
|
||||
{
|
||||
using BasicCommandBufferTest::BasicCommandBufferTest;
|
||||
|
||||
cl_int Run() override;
|
||||
bool Skip() override;
|
||||
};
|
||||
|
||||
// Test enqueueing a command-buffer twice separated by another enqueue operation
|
||||
struct InterleavedEnqueueTest : public BasicCommandBufferTest
|
||||
{
|
||||
using BasicCommandBufferTest::BasicCommandBufferTest;
|
||||
|
||||
cl_int Run() override;
|
||||
bool Skip() override;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
int MakeAndRunTest(cl_device_id device, cl_context context,
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// Copyright (c) 2025 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 "basic_command_buffer.h"
|
||||
|
||||
REGISTER_TEST(multi_flag_creation)
|
||||
{
|
||||
return MakeAndRunTest<MultiFlagCreationTest>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
REGISTER_TEST(single_ndrange)
|
||||
{
|
||||
return MakeAndRunTest<BasicEnqueueTest>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
REGISTER_TEST(interleaved_enqueue)
|
||||
{
|
||||
return MakeAndRunTest<InterleavedEnqueueTest>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
REGISTER_TEST(mixed_commands)
|
||||
{
|
||||
return MakeAndRunTest<MixedCommandsTest>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
REGISTER_TEST(explicit_flush)
|
||||
{
|
||||
return MakeAndRunTest<ExplicitFlushTest>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
@@ -12,43 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "procs.h"
|
||||
#include "harness/testHarness.h"
|
||||
|
||||
test_definition test_list[] = {
|
||||
ADD_TEST(mutable_command_info_device_query),
|
||||
ADD_TEST(mutable_command_info_buffer),
|
||||
ADD_TEST(mutable_command_properties_array),
|
||||
ADD_TEST(mutable_command_kernel),
|
||||
ADD_TEST(mutable_command_dimensions),
|
||||
ADD_TEST(mutable_command_info_type),
|
||||
ADD_TEST(mutable_command_info_queue),
|
||||
ADD_TEST(mutable_command_info_global_work_offset),
|
||||
ADD_TEST(mutable_command_info_local_work_size),
|
||||
ADD_TEST(mutable_command_info_global_work_size),
|
||||
ADD_TEST(mutable_command_full_dispatch),
|
||||
ADD_TEST(mutable_command_overwrite_update),
|
||||
ADD_TEST(mutable_command_multiple_dispatches),
|
||||
ADD_TEST(mutable_command_iterative_arg_update),
|
||||
ADD_TEST(mutable_dispatch_image_1d_arguments),
|
||||
ADD_TEST(mutable_dispatch_image_2d_arguments),
|
||||
ADD_TEST(mutable_dispatch_out_of_order),
|
||||
ADD_TEST(mutable_dispatch_simultaneous_out_of_order),
|
||||
ADD_TEST(mutable_dispatch_simultaneous_in_order),
|
||||
ADD_TEST(mutable_dispatch_simultaneous_cross_queue),
|
||||
ADD_TEST(mutable_dispatch_global_size),
|
||||
ADD_TEST(mutable_dispatch_local_size),
|
||||
ADD_TEST(mutable_dispatch_global_offset),
|
||||
ADD_TEST(mutable_dispatch_svm_arguments),
|
||||
ADD_TEST(mutable_dispatch_local_arguments),
|
||||
ADD_TEST(mutable_dispatch_global_arguments),
|
||||
ADD_TEST(mutable_dispatch_pod_arguments),
|
||||
ADD_TEST(mutable_dispatch_null_arguments),
|
||||
ADD_TEST(command_buffer_with_no_additional_work_groups),
|
||||
ADD_TEST(ndrange_with_no_additional_work_groups),
|
||||
ADD_TEST(ndrange_command_buffer_with_no_additional_work_groups),
|
||||
};
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
// A device may report the required properties of a queue that
|
||||
@@ -57,7 +22,9 @@ int main(int argc, const char *argv[])
|
||||
// for this in the tests themselves, rather than here, where we have a
|
||||
// device to query.
|
||||
const cl_command_queue_properties queue_properties = 0;
|
||||
return runTestHarnessWithCheck(argc, argv, ARRAY_SIZE(test_list), test_list,
|
||||
return runTestHarnessWithCheck(argc, argv,
|
||||
test_registry::getInstance().num_tests(),
|
||||
test_registry::getInstance().definitions(),
|
||||
false, queue_properties, nullptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -826,44 +826,31 @@ struct MutableDispatchSVMArguments : public MutableDispatchArgumentsTest
|
||||
|
||||
}
|
||||
|
||||
int test_mutable_dispatch_local_arguments(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_dispatch_local_arguments)
|
||||
{
|
||||
return MakeAndRunTest<MutableDispatchLocalArguments>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
int test_mutable_dispatch_global_arguments(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_dispatch_global_arguments)
|
||||
{
|
||||
return MakeAndRunTest<MutableDispatchGlobalArguments>(device, context,
|
||||
queue, num_elements);
|
||||
}
|
||||
|
||||
int test_mutable_dispatch_pod_arguments(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_dispatch_pod_arguments)
|
||||
{
|
||||
return MakeAndRunTest<MutableDispatchPODArguments>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
int test_mutable_dispatch_null_arguments(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_dispatch_null_arguments)
|
||||
{
|
||||
return MakeAndRunTest<MutableDispatchNullArguments>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
int test_mutable_dispatch_svm_arguments(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_dispatch_svm_arguments)
|
||||
{
|
||||
return MakeAndRunTest<MutableDispatchSVMArguments>(device, context, queue,
|
||||
num_elements);
|
||||
|
||||
@@ -492,8 +492,7 @@ struct MutableCommandFullDispatch : InfoMutableCommandBufferTest
|
||||
|
||||
}
|
||||
|
||||
int test_mutable_command_full_dispatch(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(mutable_command_full_dispatch)
|
||||
{
|
||||
return MakeAndRunTest<MutableCommandFullDispatch>(device, context, queue,
|
||||
num_elements);
|
||||
|
||||
@@ -160,9 +160,7 @@ struct MutableDispatchGlobalOffset : InfoMutableCommandBufferTest
|
||||
cl_mutable_command_khr command = nullptr;
|
||||
};
|
||||
|
||||
int test_mutable_dispatch_global_offset(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_dispatch_global_offset)
|
||||
{
|
||||
|
||||
return MakeAndRunTest<MutableDispatchGlobalOffset>(device, context, queue,
|
||||
|
||||
@@ -159,8 +159,7 @@ struct MutableDispatchGlobalSize : public InfoMutableCommandBufferTest
|
||||
cl_mutable_command_khr command = nullptr;
|
||||
};
|
||||
|
||||
int test_mutable_dispatch_global_size(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(mutable_dispatch_global_size)
|
||||
{
|
||||
return MakeAndRunTest<MutableDispatchGlobalSize>(device, context, queue,
|
||||
num_elements);
|
||||
|
||||
@@ -412,19 +412,13 @@ struct MutableDispatchImage2DArguments : public BasicMutableCommandBufferTest
|
||||
cl_mutable_command_khr command = nullptr;
|
||||
};
|
||||
|
||||
int test_mutable_dispatch_image_1d_arguments(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_dispatch_image_1d_arguments)
|
||||
{
|
||||
return MakeAndRunTest<MutableDispatchImage1DArguments>(device, context,
|
||||
queue, num_elements);
|
||||
}
|
||||
|
||||
int test_mutable_dispatch_image_2d_arguments(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_dispatch_image_2d_arguments)
|
||||
{
|
||||
return MakeAndRunTest<MutableDispatchImage2DArguments>(device, context,
|
||||
queue, num_elements);
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#include <extensionHelpers.h>
|
||||
#include "typeWrappers.h"
|
||||
#include "procs.h"
|
||||
#include "testHarness.h"
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
@@ -441,76 +440,56 @@ struct InfoLocalWorkSize : public InfoMutableCommandBufferTest
|
||||
size_t test_local_work_size = 0;
|
||||
};
|
||||
|
||||
int test_mutable_command_info_device_query(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_command_info_device_query)
|
||||
{
|
||||
return MakeAndRunTest<InfoDeviceQuery>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
int test_mutable_command_info_buffer(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(mutable_command_info_buffer)
|
||||
{
|
||||
return MakeAndRunTest<InfoBuffer>(device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_mutable_command_properties_array(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_command_properties_array)
|
||||
{
|
||||
return MakeAndRunTest<PropertiesArray>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
int test_mutable_command_kernel(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(mutable_command_kernel)
|
||||
{
|
||||
return MakeAndRunTest<Kernel>(device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_mutable_command_dimensions(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(mutable_command_dimensions)
|
||||
{
|
||||
return MakeAndRunTest<Dimensions>(device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_mutable_command_info_type(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(mutable_command_info_type)
|
||||
{
|
||||
return MakeAndRunTest<InfoType>(device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_mutable_command_info_queue(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(mutable_command_info_queue)
|
||||
{
|
||||
return MakeAndRunTest<InfoQueue>(device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_mutable_command_info_global_work_offset(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_command_info_global_work_offset)
|
||||
{
|
||||
return MakeAndRunTest<InfoGlobalWorkOffset>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
int test_mutable_command_info_global_work_size(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_command_info_global_work_size)
|
||||
{
|
||||
return MakeAndRunTest<InfoGlobalWorkSize>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
int test_mutable_command_info_local_work_size(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_command_info_local_work_size)
|
||||
{
|
||||
return MakeAndRunTest<InfoLocalWorkSize>(device, context, queue,
|
||||
num_elements);
|
||||
|
||||
@@ -212,10 +212,7 @@ struct IterativeArgUpdateDispatch : BasicMutableCommandBufferTest
|
||||
|
||||
}
|
||||
|
||||
int test_mutable_command_iterative_arg_update(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_command_iterative_arg_update)
|
||||
{
|
||||
return MakeAndRunTest<IterativeArgUpdateDispatch>(device, context, queue,
|
||||
num_elements);
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#include <extensionHelpers.h>
|
||||
#include "typeWrappers.h"
|
||||
#include "procs.h"
|
||||
#include "testHarness.h"
|
||||
#include "mutable_command_basic.h"
|
||||
#include <vector>
|
||||
@@ -166,8 +165,7 @@ struct MutableDispatchLocalSize : public InfoMutableCommandBufferTest
|
||||
cl_mutable_command_khr command = nullptr;
|
||||
};
|
||||
|
||||
int test_mutable_dispatch_local_size(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(mutable_dispatch_local_size)
|
||||
{
|
||||
return MakeAndRunTest<MutableDispatchLocalSize>(device, context, queue,
|
||||
num_elements);
|
||||
|
||||
@@ -207,10 +207,7 @@ struct MultipleCommandsDispatch : BasicMutableCommandBufferTest
|
||||
|
||||
}
|
||||
|
||||
int test_mutable_command_multiple_dispatches(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_command_multiple_dispatches)
|
||||
{
|
||||
return MakeAndRunTest<MultipleCommandsDispatch>(device, context, queue,
|
||||
num_elements);
|
||||
|
||||
@@ -215,10 +215,7 @@ struct OverwriteUpdateDispatch : BasicMutableCommandBufferTest
|
||||
|
||||
}
|
||||
|
||||
int test_mutable_command_overwrite_update(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_command_overwrite_update)
|
||||
{
|
||||
return MakeAndRunTest<OverwriteUpdateDispatch>(device, context, queue,
|
||||
num_elements);
|
||||
|
||||
@@ -605,35 +605,25 @@ struct CrossQueueSimultaneousMutableDispatchTest
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int test_mutable_dispatch_out_of_order(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(mutable_dispatch_out_of_order)
|
||||
{
|
||||
return MakeAndRunTest<SimultaneousMutableDispatchTest<false, true>>(
|
||||
device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_mutable_dispatch_simultaneous_out_of_order(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_dispatch_simultaneous_out_of_order)
|
||||
{
|
||||
return MakeAndRunTest<SimultaneousMutableDispatchTest<true, true>>(
|
||||
device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_mutable_dispatch_simultaneous_in_order(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_dispatch_simultaneous_in_order)
|
||||
{
|
||||
return MakeAndRunTest<SimultaneousMutableDispatchTest<true, false>>(
|
||||
device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_mutable_dispatch_simultaneous_cross_queue(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(mutable_dispatch_simultaneous_cross_queue)
|
||||
{
|
||||
return MakeAndRunTest<CrossQueueSimultaneousMutableDispatchTest>(
|
||||
device, context, queue, num_elements);
|
||||
|
||||
@@ -284,29 +284,21 @@ struct MutableDispatchWorkGroups : public BasicMutableCommandBufferTest
|
||||
const size_t sizeToAllocate = 64 * sizeof(cl_int);
|
||||
};
|
||||
|
||||
int test_command_buffer_with_no_additional_work_groups(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(command_buffer_with_no_additional_work_groups)
|
||||
{
|
||||
|
||||
return MakeAndRunTest<MutableDispatchWorkGroups<0>>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
int test_ndrange_with_no_additional_work_groups(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(ndrange_with_no_additional_work_groups)
|
||||
{
|
||||
|
||||
return MakeAndRunTest<MutableDispatchWorkGroups<1>>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
int test_ndrange_command_buffer_with_no_additional_work_groups(
|
||||
cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(ndrange_command_buffer_with_no_additional_work_groups)
|
||||
{
|
||||
|
||||
return MakeAndRunTest<MutableDispatchWorkGroups<2>>(device, context, queue,
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2023 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.
|
||||
//
|
||||
#ifndef CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_PROCS_H
|
||||
#define CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_PROCS_H
|
||||
|
||||
#include <CL/cl.h>
|
||||
|
||||
|
||||
// Basic mutable dispatch tests
|
||||
extern int test_mutable_command_info_device_query(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_command_info_buffer(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_command_info_type(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_command_info_queue(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_command_properties_array(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_command_kernel(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_command_dimensions(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_command_info_global_work_offset(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_command_info_local_work_size(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_command_info_global_work_size(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_dispatch_image_1d_arguments(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_dispatch_image_2d_arguments(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_dispatch_global_arguments(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_dispatch_local_arguments(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_dispatch_pod_arguments(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_dispatch_null_arguments(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_dispatch_svm_arguments(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_dispatch_out_of_order(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_dispatch_simultaneous_out_of_order(
|
||||
cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_dispatch_simultaneous_in_order(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_dispatch_simultaneous_cross_queue(
|
||||
cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_dispatch_global_size(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_dispatch_local_size(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_dispatch_global_offset(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_command_full_dispatch(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_command_overwrite_update(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_command_multiple_dispatches(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_mutable_command_iterative_arg_update(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_command_buffer_with_no_additional_work_groups(
|
||||
cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_ndrange_with_no_additional_work_groups(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements);
|
||||
extern int test_ndrange_command_buffer_with_no_additional_work_groups(
|
||||
cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
int num_elements);
|
||||
|
||||
#endif /*_CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_PROCS_H*/
|
||||
@@ -15,7 +15,6 @@
|
||||
//
|
||||
|
||||
#include "basic_command_buffer.h"
|
||||
#include "procs.h"
|
||||
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
@@ -823,10 +822,7 @@ struct CommandBufferEventSync : public BasicCommandBufferTest
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// return-events test cases for regular queue
|
||||
int test_regular_wait_for_command_buffer(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(regular_wait_for_command_buffer)
|
||||
{
|
||||
int status = TEST_PASS;
|
||||
// The approach here is that test scenario which involves out-of-order
|
||||
@@ -848,10 +844,7 @@ int test_regular_wait_for_command_buffer(cl_device_id device,
|
||||
return status;
|
||||
}
|
||||
|
||||
int test_command_buffer_wait_for_command_buffer(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(command_buffer_wait_for_command_buffer)
|
||||
{
|
||||
int status = TEST_PASS;
|
||||
// out-of-order command queue test
|
||||
@@ -871,10 +864,7 @@ int test_command_buffer_wait_for_command_buffer(cl_device_id device,
|
||||
return status;
|
||||
}
|
||||
|
||||
int test_command_buffer_wait_for_sec_command_buffer(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(command_buffer_wait_for_sec_command_buffer)
|
||||
{
|
||||
int status = TEST_PASS;
|
||||
// out-of-order command queue test
|
||||
@@ -894,8 +884,7 @@ int test_command_buffer_wait_for_sec_command_buffer(cl_device_id device,
|
||||
return status;
|
||||
}
|
||||
|
||||
int test_return_event_callback(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(return_event_callback)
|
||||
{
|
||||
int status = TEST_PASS;
|
||||
// out-of-order command queue test
|
||||
@@ -913,8 +902,7 @@ int test_return_event_callback(cl_device_id device, cl_context context,
|
||||
return status;
|
||||
}
|
||||
|
||||
int test_clwaitforevents_single(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(clwaitforevents_single)
|
||||
{
|
||||
int status = TEST_PASS;
|
||||
// out-of-order command queue test
|
||||
@@ -934,8 +922,7 @@ int test_clwaitforevents_single(cl_device_id device, cl_context context,
|
||||
return status;
|
||||
}
|
||||
|
||||
int test_clwaitforevents(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(clwaitforevents)
|
||||
{
|
||||
int status = TEST_PASS;
|
||||
// out-of-order command queue test
|
||||
@@ -953,10 +940,7 @@ int test_clwaitforevents(cl_device_id device, cl_context context,
|
||||
return status;
|
||||
}
|
||||
|
||||
int test_command_buffer_wait_for_regular(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(command_buffer_wait_for_regular)
|
||||
{
|
||||
int status = TEST_PASS;
|
||||
// out-of-order command queue test
|
||||
@@ -976,8 +960,7 @@ int test_command_buffer_wait_for_regular(cl_device_id device,
|
||||
return status;
|
||||
}
|
||||
|
||||
int test_wait_for_sec_queue_event(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(wait_for_sec_queue_event)
|
||||
{
|
||||
int status = TEST_PASS;
|
||||
// out-of-order command queue test
|
||||
@@ -1000,8 +983,7 @@ int test_wait_for_sec_queue_event(cl_device_id device, cl_context context,
|
||||
//--------------------------------------------------------------------------
|
||||
// user-events test cases
|
||||
|
||||
int test_user_event_wait(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(user_event_wait)
|
||||
{
|
||||
int status = TEST_PASS;
|
||||
// out-of-order command queue test
|
||||
@@ -1019,8 +1001,7 @@ int test_user_event_wait(cl_device_id device, cl_context context,
|
||||
return status;
|
||||
}
|
||||
|
||||
int test_user_events_wait(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(user_events_wait)
|
||||
{
|
||||
int status = TEST_PASS;
|
||||
// out-of-order command queue test
|
||||
@@ -1038,8 +1019,7 @@ int test_user_events_wait(cl_device_id device, cl_context context,
|
||||
return status;
|
||||
}
|
||||
|
||||
int test_user_event_callback(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(user_event_callback)
|
||||
{
|
||||
int status = TEST_PASS;
|
||||
// out-of-order command queue test
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "basic_command_buffer.h"
|
||||
#include "procs.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -71,15 +70,13 @@ struct FinalizeEmpty : public BasicCommandBufferTest
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
int test_finalize_invalid(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(finalize_invalid)
|
||||
{
|
||||
return MakeAndRunTest<FinalizeInvalid>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
int test_finalize_empty(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(finalize_empty)
|
||||
{
|
||||
return MakeAndRunTest<FinalizeEmpty>(device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
//
|
||||
|
||||
#include "basic_command_buffer.h"
|
||||
#include "procs.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -374,40 +373,35 @@ struct CommandBufferGetCommandBufferInfo : public BasicCommandBufferTest
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
int test_info_queues(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(info_queues)
|
||||
{
|
||||
return MakeAndRunTest<
|
||||
CommandBufferGetCommandBufferInfo<CombufInfoTestMode::CITM_QUEUES>>(
|
||||
device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_info_ref_count(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(info_ref_count)
|
||||
{
|
||||
return MakeAndRunTest<
|
||||
CommandBufferGetCommandBufferInfo<CombufInfoTestMode::CITM_REF_COUNT>>(
|
||||
device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_info_state(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(info_state)
|
||||
{
|
||||
return MakeAndRunTest<
|
||||
CommandBufferGetCommandBufferInfo<CombufInfoTestMode::CITM_STATE>>(
|
||||
device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_info_prop_array(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(info_prop_array)
|
||||
{
|
||||
return MakeAndRunTest<
|
||||
CommandBufferGetCommandBufferInfo<CombufInfoTestMode::CITM_PROP_ARRAY>>(
|
||||
device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_info_context(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(info_context)
|
||||
{
|
||||
return MakeAndRunTest<
|
||||
CommandBufferGetCommandBufferInfo<CombufInfoTestMode::CITM_CONTEXT>>(
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
//
|
||||
|
||||
#include "basic_command_buffer.h"
|
||||
#include "procs.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -337,15 +336,13 @@ struct OutOfOrderTest : public BasicCommandBufferTest
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int test_out_of_order(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(out_of_order)
|
||||
{
|
||||
return MakeAndRunTest<OutOfOrderTest<false>>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
int test_simultaneous_out_of_order(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(simultaneous_out_of_order)
|
||||
{
|
||||
return MakeAndRunTest<OutOfOrderTest<true>>(device, context, queue,
|
||||
num_elements);
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <harness/os_helpers.h>
|
||||
|
||||
#include "basic_command_buffer.h"
|
||||
#include "procs.h"
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#if defined(__APPLE__)
|
||||
@@ -524,15 +523,13 @@ struct CommandBufferPrintfTest : public BasicCommandBufferTest
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int test_basic_printf(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(basic_printf)
|
||||
{
|
||||
return MakeAndRunTest<CommandBufferPrintfTest<false>>(device, context,
|
||||
queue, num_elements);
|
||||
}
|
||||
|
||||
int test_simultaneous_printf(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(simultaneous_printf)
|
||||
{
|
||||
return MakeAndRunTest<CommandBufferPrintfTest<true>>(device, context, queue,
|
||||
num_elements);
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
//
|
||||
|
||||
#include "basic_command_buffer.h"
|
||||
#include "procs.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -357,22 +356,19 @@ struct CommandBufferSubstituteQueueProfiling : public BasicCommandBufferTest
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
int test_basic_profiling(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(basic_profiling)
|
||||
{
|
||||
return MakeAndRunTest<CommandBufferProfiling<false>>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
int test_simultaneous_profiling(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(simultaneous_profiling)
|
||||
{
|
||||
return MakeAndRunTest<CommandBufferProfiling<true>>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
int test_substitute_queue_profiling(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(substitute_queue_profiling)
|
||||
{
|
||||
return MakeAndRunTest<CommandBufferSubstituteQueueProfiling>(
|
||||
device, context, queue, num_elements);
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "basic_command_buffer.h"
|
||||
#include "procs.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -396,38 +395,31 @@ struct QueueOrderTest : public BasicCommandBufferTest
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
int test_queue_substitution(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(queue_substitution)
|
||||
{
|
||||
return MakeAndRunTest<SubstituteQueueTest<false, false>>(
|
||||
device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_properties_queue_substitution(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(properties_queue_substitution)
|
||||
{
|
||||
return MakeAndRunTest<SubstituteQueueTest<true, false>>(
|
||||
device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_simultaneous_queue_substitution(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(simultaneous_queue_substitution)
|
||||
{
|
||||
return MakeAndRunTest<SubstituteQueueTest<false, true>>(
|
||||
device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_queue_substitute_in_order(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(queue_substitute_in_order)
|
||||
{
|
||||
return MakeAndRunTest<QueueOrderTest<false>>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
int test_queue_substitute_out_of_order(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(queue_substitute_out_of_order)
|
||||
{
|
||||
return MakeAndRunTest<QueueOrderTest<true>>(device, context, queue,
|
||||
num_elements);
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
//
|
||||
|
||||
#include "basic_command_buffer.h"
|
||||
#include "procs.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -306,15 +305,13 @@ struct CommandBufferSetKernelArg : public BasicCommandBufferTest
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int test_basic_set_kernel_arg(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(basic_set_kernel_arg)
|
||||
{
|
||||
return MakeAndRunTest<CommandBufferSetKernelArg<false>>(
|
||||
device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_pending_set_kernel_arg(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(pending_set_kernel_arg)
|
||||
{
|
||||
return MakeAndRunTest<CommandBufferSetKernelArg<true>>(device, context,
|
||||
queue, num_elements);
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "basic_command_buffer.h"
|
||||
#include "procs.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -146,8 +145,7 @@ struct BarrierWithWaitListKHR : public BasicCommandBufferTest
|
||||
};
|
||||
|
||||
|
||||
int test_barrier_wait_list(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(barrier_wait_list)
|
||||
{
|
||||
return MakeAndRunTest<BarrierWithWaitListKHR>(device, context, queue,
|
||||
num_elements);
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "basic_command_buffer.h"
|
||||
#include "svm_command_basic.h"
|
||||
#include "harness/typeWrappers.h"
|
||||
#include "procs.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -563,42 +562,36 @@ struct CopyBufferRectKHR : public BasicCommandBufferTest
|
||||
};
|
||||
};
|
||||
|
||||
int test_copy_image(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(copy_image)
|
||||
{
|
||||
return MakeAndRunTest<CopyImageKHR>(device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_copy_buffer(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(copy_buffer)
|
||||
{
|
||||
return MakeAndRunTest<CopyBufferKHR>(device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_copy_svm_buffer(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(copy_svm_buffer)
|
||||
{
|
||||
return MakeAndRunTest<CopySVMBufferKHR>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
|
||||
int test_copy_buffer_to_image(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(copy_buffer_to_image)
|
||||
{
|
||||
return MakeAndRunTest<CopyBufferToImageKHR>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
int test_copy_image_to_buffer(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(copy_image_to_buffer)
|
||||
{
|
||||
return MakeAndRunTest<CopyImageToBufferKHR>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
int test_copy_buffer_rect(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(copy_buffer_rect)
|
||||
{
|
||||
return MakeAndRunTest<CopyBufferRectKHR>(device, context, queue,
|
||||
num_elements);
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "basic_command_buffer.h"
|
||||
#include "procs.h"
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
@@ -222,33 +221,28 @@ struct ReferenceCount : public BasicCommandBufferTest
|
||||
};
|
||||
};
|
||||
|
||||
int test_event_info_command_type(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(event_info_command_type)
|
||||
{
|
||||
return MakeAndRunTest<CommandType>(device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_event_info_command_queue(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(event_info_command_queue)
|
||||
{
|
||||
return MakeAndRunTest<CommandQueue>(device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_event_info_context(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(event_info_context)
|
||||
{
|
||||
return MakeAndRunTest<Context>(device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_event_info_execution_status(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(event_info_execution_status)
|
||||
{
|
||||
return MakeAndRunTest<ExecutionStatus>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
int test_event_info_reference_count(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(event_info_reference_count)
|
||||
{
|
||||
return MakeAndRunTest<ReferenceCount>(device, context, queue, num_elements);
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "basic_command_buffer.h"
|
||||
#include "svm_command_basic.h"
|
||||
#include "harness/typeWrappers.h"
|
||||
#include "procs.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -230,22 +229,19 @@ struct FillSVMBufferKHR : public BasicSVMCommandBufferTest
|
||||
};
|
||||
};
|
||||
|
||||
int test_fill_buffer(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(fill_buffer)
|
||||
{
|
||||
return MakeAndRunTest<FillBufferKHR>(device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_fill_svm_buffer(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(fill_svm_buffer)
|
||||
{
|
||||
return MakeAndRunTest<FillSVMBufferKHR>(device, context, queue,
|
||||
num_elements);
|
||||
}
|
||||
|
||||
|
||||
int test_fill_image(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
REGISTER_TEST(fill_image)
|
||||
{
|
||||
return MakeAndRunTest<FillImageKHR>(device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//
|
||||
// Copyright (c) 2024 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -11,17 +12,25 @@
|
||||
// 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.
|
||||
//
|
||||
#ifndef CL_KHR_KERNEL_CLOCK_PROCS_H
|
||||
#define CL_KHR_KERNEL_CLOCK_PROCS_H
|
||||
|
||||
#include <CL/cl.h>
|
||||
#pragma once
|
||||
|
||||
int test_device_scope(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements);
|
||||
int test_workgroup_scope(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements);
|
||||
int test_subgroup_scope(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements);
|
||||
#include "basic_command_buffer.h"
|
||||
#include <type_traits>
|
||||
|
||||
#endif /*CL_KHR_KERNEL_CLOCK_PROCS_H*/
|
||||
template <class TBase>
|
||||
struct CommandBufferWithImmutableMemoryObjectsTest : public TBase
|
||||
{
|
||||
using TBase::TBase;
|
||||
|
||||
static_assert(std::is_base_of<BasicCommandBufferTest, TBase>::value,
|
||||
"TBase must be BasicCommandBufferTest or a derived class");
|
||||
|
||||
bool Skip() override
|
||||
{
|
||||
bool is_immutable_memory_objects_supported = is_extension_available(
|
||||
BasicCommandBufferTest::device, "cl_ext_immutable_memory_objects");
|
||||
|
||||
return !is_immutable_memory_objects_supported || TBase::Skip();
|
||||
}
|
||||
};
|
||||
@@ -12,157 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "procs.h"
|
||||
#include "harness/testHarness.h"
|
||||
|
||||
test_definition test_list[] = {
|
||||
ADD_TEST(multi_flag_creation),
|
||||
ADD_TEST(single_ndrange),
|
||||
ADD_TEST(interleaved_enqueue),
|
||||
ADD_TEST(mixed_commands),
|
||||
ADD_TEST(explicit_flush),
|
||||
ADD_TEST(out_of_order),
|
||||
ADD_TEST(simultaneous_out_of_order),
|
||||
ADD_TEST(info_queues),
|
||||
ADD_TEST(info_ref_count),
|
||||
ADD_TEST(info_state),
|
||||
ADD_TEST(info_prop_array),
|
||||
ADD_TEST(info_context),
|
||||
ADD_TEST(basic_profiling),
|
||||
ADD_TEST(simultaneous_profiling),
|
||||
ADD_TEST(substitute_queue_profiling),
|
||||
ADD_TEST(regular_wait_for_command_buffer),
|
||||
ADD_TEST(command_buffer_wait_for_command_buffer),
|
||||
ADD_TEST(command_buffer_wait_for_sec_command_buffer),
|
||||
ADD_TEST(return_event_callback),
|
||||
ADD_TEST(clwaitforevents_single),
|
||||
ADD_TEST(clwaitforevents),
|
||||
ADD_TEST(command_buffer_wait_for_regular),
|
||||
ADD_TEST(wait_for_sec_queue_event),
|
||||
ADD_TEST(user_event_wait),
|
||||
ADD_TEST(user_events_wait),
|
||||
ADD_TEST(user_event_callback),
|
||||
ADD_TEST(queue_substitution),
|
||||
ADD_TEST(properties_queue_substitution),
|
||||
ADD_TEST(simultaneous_queue_substitution),
|
||||
ADD_TEST(queue_substitute_in_order),
|
||||
ADD_TEST(queue_substitute_out_of_order),
|
||||
ADD_TEST(fill_image),
|
||||
ADD_TEST(fill_buffer),
|
||||
ADD_TEST(fill_svm_buffer),
|
||||
ADD_TEST(copy_image),
|
||||
ADD_TEST(copy_buffer),
|
||||
ADD_TEST(copy_svm_buffer),
|
||||
ADD_TEST(copy_buffer_to_image),
|
||||
ADD_TEST(copy_image_to_buffer),
|
||||
ADD_TEST(copy_buffer_rect),
|
||||
ADD_TEST(barrier_wait_list),
|
||||
ADD_TEST(basic_printf),
|
||||
ADD_TEST(simultaneous_printf),
|
||||
ADD_TEST(basic_set_kernel_arg),
|
||||
ADD_TEST(pending_set_kernel_arg),
|
||||
ADD_TEST(event_info_command_type),
|
||||
ADD_TEST(event_info_command_queue),
|
||||
ADD_TEST(event_info_execution_status),
|
||||
ADD_TEST(event_info_context),
|
||||
ADD_TEST(event_info_reference_count),
|
||||
ADD_TEST(finalize_invalid),
|
||||
ADD_TEST(finalize_empty),
|
||||
// Command-buffer negative tests
|
||||
ADD_TEST(negative_retain_command_buffer_invalid_command_buffer),
|
||||
ADD_TEST(negative_release_command_buffer_invalid_command_buffer),
|
||||
ADD_TEST(negative_finalize_command_buffer_invalid_command_buffer),
|
||||
ADD_TEST(negative_finalize_command_buffer_not_recording_state),
|
||||
ADD_TEST(negative_command_buffer_command_fill_buffer_queue_not_null),
|
||||
ADD_TEST(negative_command_buffer_command_fill_buffer_context_not_same),
|
||||
ADD_TEST(
|
||||
negative_command_buffer_command_fill_buffer_sync_points_null_or_num_zero),
|
||||
ADD_TEST(
|
||||
negative_command_buffer_command_fill_buffer_invalid_command_buffer),
|
||||
ADD_TEST(
|
||||
negative_command_buffer_command_fill_buffer_finalized_command_buffer),
|
||||
ADD_TEST(
|
||||
negative_command_buffer_command_fill_buffer_mutable_handle_not_null),
|
||||
ADD_TEST(negative_command_buffer_command_fill_image_queue_not_null),
|
||||
ADD_TEST(negative_command_buffer_command_fill_image_context_not_same),
|
||||
ADD_TEST(
|
||||
negative_command_buffer_command_fill_image_sync_points_null_or_num_zero),
|
||||
ADD_TEST(negative_command_buffer_command_fill_image_invalid_command_buffer),
|
||||
ADD_TEST(
|
||||
negative_command_buffer_command_fill_image_finalized_command_buffer),
|
||||
ADD_TEST(
|
||||
negative_command_buffer_command_fill_image_mutable_handle_not_null),
|
||||
ADD_TEST(negative_create_command_buffer_num_queues),
|
||||
ADD_TEST(negative_create_command_buffer_null_queues),
|
||||
ADD_TEST(negative_create_command_buffer_repeated_properties),
|
||||
ADD_TEST(negative_create_command_buffer_not_supported_properties),
|
||||
ADD_TEST(negative_command_ndrange_queue_not_null),
|
||||
ADD_TEST(negative_command_ndrange_kernel_with_different_context),
|
||||
ADD_TEST(negative_command_ndrange_kernel_sync_points_null_or_num_zero),
|
||||
ADD_TEST(negative_command_ndrange_kernel_invalid_command_buffer),
|
||||
ADD_TEST(negative_command_ndrange_kernel_invalid_properties),
|
||||
ADD_TEST(negative_command_ndrange_kernel_command_buffer_finalized),
|
||||
ADD_TEST(negative_command_ndrange_kernel_mutable_handle_not_null),
|
||||
ADD_TEST(negative_command_ndrange_kernel_not_support_printf),
|
||||
ADD_TEST(negative_command_ndrange_kernel_with_enqueue_call),
|
||||
ADD_TEST(negative_command_buffer_command_copy_buffer_queue_not_null),
|
||||
ADD_TEST(negative_command_buffer_command_copy_buffer_different_contexts),
|
||||
ADD_TEST(
|
||||
negative_command_buffer_command_copy_buffer_sync_points_null_or_num_zero),
|
||||
ADD_TEST(
|
||||
negative_command_buffer_command_copy_buffer_invalid_command_buffer),
|
||||
ADD_TEST(
|
||||
negative_command_buffer_command_copy_buffer_finalized_command_buffer),
|
||||
ADD_TEST(
|
||||
negative_command_buffer_command_copy_buffer_mutable_handle_not_null),
|
||||
ADD_TEST(negative_command_buffer_command_copy_image_queue_not_null),
|
||||
ADD_TEST(negative_command_buffer_command_copy_image_different_contexts),
|
||||
ADD_TEST(
|
||||
negative_command_buffer_command_copy_image_sync_points_null_or_num_zero),
|
||||
ADD_TEST(negative_command_buffer_command_copy_image_invalid_command_buffer),
|
||||
ADD_TEST(
|
||||
negative_command_buffer_command_copy_image_finalized_command_buffer),
|
||||
ADD_TEST(
|
||||
negative_command_buffer_command_copy_image_mutable_handle_not_null),
|
||||
ADD_TEST(negative_get_command_buffer_info_invalid_command_buffer),
|
||||
ADD_TEST(negative_get_command_buffer_info_not_supported_param_name),
|
||||
ADD_TEST(negative_get_command_buffer_info_queues),
|
||||
ADD_TEST(negative_get_command_buffer_info_ref_count),
|
||||
ADD_TEST(negative_get_command_buffer_info_state),
|
||||
ADD_TEST(negative_get_command_buffer_info_prop_array),
|
||||
ADD_TEST(negative_get_command_buffer_info_context),
|
||||
ADD_TEST(negative_command_buffer_command_svm_queue_not_null),
|
||||
ADD_TEST(negative_command_buffer_command_svm_sync_points_null_or_num_zero),
|
||||
ADD_TEST(negative_command_buffer_command_svm_invalid_command_buffer),
|
||||
ADD_TEST(negative_command_buffer_command_svm_finalized_command_buffer),
|
||||
ADD_TEST(negative_command_buffer_command_svm_mutable_handle_not_null),
|
||||
ADD_TEST(negative_command_buffer_copy_image_queue_not_null),
|
||||
ADD_TEST(negative_command_buffer_copy_image_context_not_same),
|
||||
ADD_TEST(negative_command_buffer_copy_image_sync_points_null_or_num_zero),
|
||||
ADD_TEST(negative_command_buffer_copy_image_invalid_command_buffer),
|
||||
ADD_TEST(negative_command_buffer_copy_image_finalized_command_buffer),
|
||||
ADD_TEST(negative_command_buffer_copy_image_mutable_handle_not_null),
|
||||
ADD_TEST(negative_command_buffer_barrier_not_null_queue),
|
||||
ADD_TEST(negative_command_buffer_barrier_invalid_command_buffer),
|
||||
ADD_TEST(negative_command_buffer_barrier_buffer_finalized),
|
||||
ADD_TEST(negative_command_buffer_barrier_mutable_handle_not_null),
|
||||
ADD_TEST(negative_command_buffer_barrier_sync_points_null_or_num_zero),
|
||||
ADD_TEST(negative_enqueue_command_buffer_invalid_command_buffer),
|
||||
ADD_TEST(negative_enqueue_command_buffer_not_finalized),
|
||||
ADD_TEST(
|
||||
negative_enqueue_command_buffer_without_simultaneous_no_pending_state),
|
||||
ADD_TEST(negative_enqueue_command_buffer_null_queues_num_queues),
|
||||
ADD_TEST(
|
||||
negative_enqueue_command_buffer_num_queues_not_zero_different_while_buffer_creation),
|
||||
ADD_TEST(negative_enqueue_command_buffer_not_valid_queue_in_queues),
|
||||
ADD_TEST(negative_enqueue_queue_with_different_context),
|
||||
ADD_TEST(negative_enqueue_command_buffer_different_context_than_event),
|
||||
ADD_TEST(negative_enqueue_event_wait_list_null_or_events_null),
|
||||
ADD_TEST(negative_enqueue_queue_without_reqd_properties),
|
||||
ADD_TEST(negative_enqueue_with_unsupported_queue_property),
|
||||
ADD_TEST(negative_enqueue_inconsistent_device),
|
||||
};
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
// A device may report the required properties of a queue that
|
||||
@@ -171,6 +22,8 @@ int main(int argc, const char *argv[])
|
||||
// for this in the tests themselves, rather than here, where we have a
|
||||
// device to query.
|
||||
const cl_command_queue_properties queue_properties = 0;
|
||||
return runTestHarnessWithCheck(argc, argv, ARRAY_SIZE(test_list), test_list,
|
||||
return runTestHarnessWithCheck(argc, argv,
|
||||
test_registry::getInstance().num_tests(),
|
||||
test_registry::getInstance().definitions(),
|
||||
false, queue_properties, nullptr);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "basic_command_buffer.h"
|
||||
#include "procs.h"
|
||||
#include <vector>
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -159,42 +158,31 @@ struct CommandBufferBarrierSyncPointsNullOrNumZero
|
||||
};
|
||||
};
|
||||
|
||||
int test_negative_command_buffer_barrier_not_null_queue(cl_device_id device,
|
||||
cl_context context,
|
||||
cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(negative_command_buffer_barrier_not_null_queue)
|
||||
{
|
||||
return MakeAndRunTest<CommandBufferBarrierNotNullQueue>(
|
||||
device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_negative_command_buffer_barrier_invalid_command_buffer(
|
||||
cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(negative_command_buffer_barrier_invalid_command_buffer)
|
||||
{
|
||||
return MakeAndRunTest<CommandBufferBarrierInvalidCommandBuffer>(
|
||||
device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_negative_command_buffer_barrier_buffer_finalized(
|
||||
cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(negative_command_buffer_barrier_buffer_finalized)
|
||||
{
|
||||
return MakeAndRunTest<CommandBufferBarrierBufferFinalized>(
|
||||
device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_negative_command_buffer_barrier_mutable_handle_not_null(
|
||||
cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(negative_command_buffer_barrier_mutable_handle_not_null)
|
||||
{
|
||||
return MakeAndRunTest<CommandBufferBarrierMutableHandleNotNull>(
|
||||
device, context, queue, num_elements);
|
||||
}
|
||||
|
||||
int test_negative_command_buffer_barrier_sync_points_null_or_num_zero(
|
||||
cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
int num_elements)
|
||||
REGISTER_TEST(negative_command_buffer_barrier_sync_points_null_or_num_zero)
|
||||
{
|
||||
return MakeAndRunTest<CommandBufferBarrierSyncPointsNullOrNumZero>(
|
||||
device, context, queue, num_elements);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user