mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-20 22:39:03 +00:00
Synchronise with Khronos-private Gitlab branch
The maintenance of the conformance tests is moving to Github. This commit contains all the changes that have been done in Gitlab since the first public release of the conformance tests. Signed-off-by: Kevin Petit <kevin.petit@arm.com>
This commit is contained in:
@@ -1,26 +1,26 @@
|
||||
|
||||
PRODUCTS = harness/\
|
||||
|
||||
# utils/
|
||||
|
||||
TOP=$(shell pwd)
|
||||
|
||||
all: $(PRODUCTS)
|
||||
|
||||
clean:
|
||||
@for testdir in $(dir $(PRODUCTS)) ; \
|
||||
do ( \
|
||||
echo "==================================================================================" ; \
|
||||
echo "Cleaning $$testdir" ; \
|
||||
echo "==================================================================================" ; \
|
||||
cd $$testdir && make clean \
|
||||
); \
|
||||
done \
|
||||
|
||||
$(PRODUCTS):
|
||||
@echo "==================================================================================" ;
|
||||
@echo "(`date "+%H:%M:%S"`) Make $@" ;
|
||||
@echo "==================================================================================" ;
|
||||
cd $(dir $@) && make
|
||||
|
||||
.PHONY: clean $(PRODUCTS) all
|
||||
|
||||
PRODUCTS = harness/\
|
||||
|
||||
# utils/
|
||||
|
||||
TOP=$(shell pwd)
|
||||
|
||||
all: $(PRODUCTS)
|
||||
|
||||
clean:
|
||||
@for testdir in $(dir $(PRODUCTS)) ; \
|
||||
do ( \
|
||||
echo "==================================================================================" ; \
|
||||
echo "Cleaning $$testdir" ; \
|
||||
echo "==================================================================================" ; \
|
||||
cd $$testdir && make clean \
|
||||
); \
|
||||
done \
|
||||
|
||||
$(PRODUCTS):
|
||||
@echo "==================================================================================" ;
|
||||
@echo "(`date "+%H:%M:%S"`) Make $@" ;
|
||||
@echo "==================================================================================" ;
|
||||
cd $(dir $@) && make
|
||||
|
||||
.PHONY: clean $(PRODUCTS) all
|
||||
|
||||
@@ -1,52 +1,52 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _gl_headers_h
|
||||
#define _gl_headers_h
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#if defined(CGL_VERSION_1_3)
|
||||
#include <OpenGL/gl3.h>
|
||||
#include <OpenGL/gl3ext.h>
|
||||
#else
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glext.h>
|
||||
#endif
|
||||
#include <GLUT/glut.h>
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <GL/glew.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#ifdef _WIN32
|
||||
#include <GL/glut.h>
|
||||
#else
|
||||
#include <GL/freeglut.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
GLboolean gluCheckExtension(const GLubyte *extName, const GLubyte *extString);
|
||||
// No glutGetProcAddress in the standard glut v3.7.
|
||||
#define glutGetProcAddress(procName) wglGetProcAddress(procName)
|
||||
#endif
|
||||
|
||||
|
||||
#endif // __gl_headers_h
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _gl_headers_h
|
||||
#define _gl_headers_h
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#if defined(CGL_VERSION_1_3)
|
||||
#include <OpenGL/gl3.h>
|
||||
#include <OpenGL/gl3ext.h>
|
||||
#else
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glext.h>
|
||||
#endif
|
||||
#include <GLUT/glut.h>
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <GL/glew.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#ifdef _WIN32
|
||||
#include <GL/glut.h>
|
||||
#else
|
||||
#include <GL/freeglut.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
GLboolean gluCheckExtension(const GLubyte *extName, const GLubyte *extString);
|
||||
// No glutGetProcAddress in the standard glut v3.7.
|
||||
#define glutGetProcAddress(procName) wglGetProcAddress(procName)
|
||||
#endif
|
||||
|
||||
|
||||
#endif // __gl_headers_h
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,288 +1,288 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _helpers_h
|
||||
#define _helpers_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if !defined (__APPLE__)
|
||||
#include <CL/cl.h>
|
||||
#include "gl_headers.h"
|
||||
#include <CL/cl_gl.h>
|
||||
#else
|
||||
#include "gl_headers.h"
|
||||
#endif
|
||||
|
||||
#include "../../test_common/harness/errorHelpers.h"
|
||||
#include "../../test_common/harness/kernelHelpers.h"
|
||||
#include "../../test_common/harness/threadTesting.h"
|
||||
#include "../../test_common/harness/typeWrappers.h"
|
||||
#include "../../test_common/harness/conversions.h"
|
||||
#include "../../test_common/harness/mt19937.h"
|
||||
|
||||
typedef cl_mem
|
||||
(CL_API_CALL *clCreateFromGLBuffer_fn)(cl_context context,
|
||||
cl_mem_flags flags,
|
||||
GLuint bufobj,
|
||||
int * errcode_ret);
|
||||
|
||||
typedef cl_mem
|
||||
(CL_API_CALL *clCreateFromGLTexture_fn)(cl_context context ,
|
||||
cl_mem_flags flags ,
|
||||
GLenum target ,
|
||||
GLint miplevel ,
|
||||
GLuint texture ,
|
||||
cl_int * errcode_ret) ;
|
||||
|
||||
typedef cl_mem
|
||||
(CL_API_CALL *clCreateFromGLTexture2D_fn)(cl_context context ,
|
||||
cl_mem_flags flags ,
|
||||
GLenum target ,
|
||||
GLint miplevel ,
|
||||
GLuint texture ,
|
||||
cl_int * errcode_ret) ;
|
||||
|
||||
typedef cl_mem
|
||||
(CL_API_CALL *clCreateFromGLTexture3D_fn)(cl_context context ,
|
||||
cl_mem_flags flags ,
|
||||
GLenum target ,
|
||||
GLint miplevel ,
|
||||
GLuint texture ,
|
||||
cl_int * errcode_ret) ;
|
||||
|
||||
typedef cl_mem
|
||||
(CL_API_CALL *clCreateFromGLRenderbuffer_fn)(cl_context context ,
|
||||
cl_mem_flags flags ,
|
||||
GLuint renderbuffer ,
|
||||
cl_int * errcode_ret) ;
|
||||
|
||||
typedef cl_int
|
||||
(CL_API_CALL *clGetGLObjectInfo_fn)(cl_mem memobj ,
|
||||
cl_gl_object_type * gl_object_type ,
|
||||
GLuint * gl_object_name) ;
|
||||
|
||||
typedef cl_int
|
||||
(CL_API_CALL *clGetGLTextureInfo_fn)(cl_mem memobj ,
|
||||
cl_gl_texture_info param_name ,
|
||||
size_t param_value_size ,
|
||||
void * param_value ,
|
||||
size_t * param_value_size_ret) ;
|
||||
|
||||
typedef cl_int
|
||||
(CL_API_CALL *clEnqueueAcquireGLObjects_fn)(cl_command_queue command_queue ,
|
||||
cl_uint num_objects ,
|
||||
const cl_mem * mem_objects ,
|
||||
cl_uint num_events_in_wait_list ,
|
||||
const cl_event * event_wait_list ,
|
||||
cl_event * event) ;
|
||||
|
||||
typedef cl_int
|
||||
(CL_API_CALL *clEnqueueReleaseGLObjects_fn)(cl_command_queue command_queue ,
|
||||
cl_uint num_objects ,
|
||||
const cl_mem * mem_objects ,
|
||||
cl_uint num_events_in_wait_list ,
|
||||
const cl_event * event_wait_list ,
|
||||
cl_event * event) ;
|
||||
|
||||
|
||||
extern clCreateFromGLBuffer_fn clCreateFromGLBuffer_ptr;
|
||||
extern clCreateFromGLTexture_fn clCreateFromGLTexture_ptr;
|
||||
extern clCreateFromGLTexture2D_fn clCreateFromGLTexture2D_ptr;
|
||||
extern clCreateFromGLTexture3D_fn clCreateFromGLTexture3D_ptr;
|
||||
extern clCreateFromGLRenderbuffer_fn clCreateFromGLRenderbuffer_ptr;
|
||||
extern clGetGLObjectInfo_fn clGetGLObjectInfo_ptr;
|
||||
extern clGetGLTextureInfo_fn clGetGLTextureInfo_ptr;
|
||||
extern clEnqueueAcquireGLObjects_fn clEnqueueAcquireGLObjects_ptr;
|
||||
extern clEnqueueReleaseGLObjects_fn clEnqueueReleaseGLObjects_ptr;
|
||||
|
||||
|
||||
class glBufferWrapper
|
||||
{
|
||||
public:
|
||||
glBufferWrapper() { mBuffer = 0; }
|
||||
glBufferWrapper( GLuint b ) { mBuffer = b; }
|
||||
~glBufferWrapper() { if( mBuffer != 0 ) glDeleteBuffers( 1, &mBuffer ); }
|
||||
|
||||
glBufferWrapper & operator=( const GLuint &rhs ) { mBuffer = rhs; return *this; }
|
||||
operator GLuint() { return mBuffer; }
|
||||
operator GLuint *() { return &mBuffer; }
|
||||
|
||||
GLuint * operator&() { return &mBuffer; }
|
||||
|
||||
bool operator==( GLuint rhs ) { return mBuffer == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
GLuint mBuffer;
|
||||
};
|
||||
|
||||
class glTextureWrapper
|
||||
{
|
||||
public:
|
||||
glTextureWrapper() { mHandle = 0; }
|
||||
glTextureWrapper( GLuint b ) { mHandle = b; }
|
||||
~glTextureWrapper() {
|
||||
if( mHandle != 0 ) glDeleteTextures( 1, &mHandle );
|
||||
}
|
||||
|
||||
glTextureWrapper & operator=( const GLuint &rhs ) { mHandle = rhs; return *this; }
|
||||
operator GLuint() { return mHandle; }
|
||||
operator GLuint *() { return &mHandle; }
|
||||
|
||||
GLuint * operator&() { return &mHandle; }
|
||||
|
||||
bool operator==( GLuint rhs ) { return mHandle == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
// The texture handle.
|
||||
GLuint mHandle;
|
||||
};
|
||||
|
||||
class glRenderbufferWrapper
|
||||
{
|
||||
public:
|
||||
glRenderbufferWrapper() { mBuffer = 0; }
|
||||
glRenderbufferWrapper( GLuint b ) { mBuffer = b; }
|
||||
~glRenderbufferWrapper() { if( mBuffer != 0 ) glDeleteRenderbuffersEXT( 1, &mBuffer ); }
|
||||
|
||||
glRenderbufferWrapper & operator=( const GLuint &rhs ) { mBuffer = rhs; return *this; }
|
||||
operator GLuint() { return mBuffer; }
|
||||
operator GLuint *() { return &mBuffer; }
|
||||
|
||||
GLuint * operator&() { return &mBuffer; }
|
||||
|
||||
bool operator==( GLuint rhs ) { return mBuffer == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
GLuint mBuffer;
|
||||
};
|
||||
|
||||
class glFramebufferWrapper
|
||||
{
|
||||
public:
|
||||
glFramebufferWrapper() { mBuffer = 0; }
|
||||
glFramebufferWrapper( GLuint b ) { mBuffer = b; }
|
||||
~glFramebufferWrapper() { if( mBuffer != 0 ) glDeleteFramebuffersEXT( 1, &mBuffer ); }
|
||||
|
||||
glFramebufferWrapper & operator=( const GLuint &rhs ) { mBuffer = rhs; return *this; }
|
||||
operator GLuint() { return mBuffer; }
|
||||
operator GLuint *() { return &mBuffer; }
|
||||
|
||||
GLuint * operator&() { return &mBuffer; }
|
||||
|
||||
bool operator==( GLuint rhs ) { return mBuffer == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
GLuint mBuffer;
|
||||
};
|
||||
|
||||
|
||||
// Helper functions (defined in helpers.cpp)
|
||||
|
||||
extern void * CreateGLTexture1DArray( size_t width, size_t length,
|
||||
GLenum target, GLenum glFormat, GLenum internalFormat, GLenum glType,
|
||||
ExplicitType type, GLuint *outTextureID, int *outError,
|
||||
bool allocateMem, MTdata d);
|
||||
|
||||
extern void * CreateGLTexture2DArray( size_t width, size_t height, size_t length,
|
||||
GLenum target, GLenum glFormat, GLenum internalFormat, GLenum glType,
|
||||
ExplicitType type, GLuint *outTextureID, int *outError,
|
||||
bool allocateMem, MTdata d);
|
||||
|
||||
extern void * CreateGLTextureBuffer( size_t width,
|
||||
GLenum target, GLenum glFormat, GLenum internalFormat, GLenum glType,
|
||||
ExplicitType type, GLuint *outTex, GLuint *outBuf, int *outError,
|
||||
bool allocateMem, MTdata d);
|
||||
|
||||
extern void * CreateGLTexture1D(size_t width,
|
||||
GLenum target, GLenum glFormat,
|
||||
GLenum internalFormat, GLenum glType,
|
||||
ExplicitType type, GLuint *outTextureID,
|
||||
int *outError, bool allocateMem, MTdata d );
|
||||
|
||||
extern void * CreateGLTexture2D( size_t width, size_t height,
|
||||
GLenum target, GLenum glFormat,
|
||||
GLenum internalFormat, GLenum glType,
|
||||
ExplicitType type, GLuint *outTextureID,
|
||||
int *outError, bool allocateMem, MTdata d );
|
||||
|
||||
|
||||
extern void * CreateGLTexture3D( size_t width, size_t height, size_t depth,
|
||||
GLenum target, GLenum glFormat,
|
||||
GLenum internalFormat, GLenum glType,
|
||||
ExplicitType type, GLuint *outTextureID,
|
||||
int *outError, MTdata d, bool allocateMem = true );
|
||||
|
||||
extern void * ReadGLTexture( GLenum glTarget, GLuint glTexture, GLuint glBuf, GLint width,
|
||||
GLenum glFormat, GLenum glInternalFormat,
|
||||
GLenum glType, ExplicitType typeToReadAs,
|
||||
size_t outWidth, size_t outHeight );
|
||||
|
||||
extern int CreateGLRenderbufferRaw( GLsizei width, GLsizei height,
|
||||
GLenum target, GLenum glFormat,
|
||||
GLenum internalFormat, GLenum glType,
|
||||
GLuint *outFramebuffer,
|
||||
GLuint *outRenderbuffer );
|
||||
|
||||
extern void * CreateGLRenderbuffer( GLsizei width, GLsizei height,
|
||||
GLenum target, GLenum glFormat,
|
||||
GLenum internalFormat, GLenum glType,
|
||||
ExplicitType type,
|
||||
GLuint *outFramebuffer,
|
||||
GLuint *outRenderbuffer,
|
||||
int *outError, MTdata d, bool allocateMem );
|
||||
|
||||
extern void * ReadGLRenderbuffer( GLuint glFramebuffer, GLuint glRenderbuffer,
|
||||
GLenum attachment, GLenum glFormat,
|
||||
GLenum glInternalFormat, GLenum glType,
|
||||
ExplicitType typeToReadAs,
|
||||
size_t outWidth, size_t outHeight );
|
||||
|
||||
extern void DumpGLBuffer(GLenum type, size_t width, size_t height, void* buffer);
|
||||
extern const char *GetGLTypeName( GLenum type );
|
||||
extern const char *GetGLAttachmentName( GLenum att );
|
||||
extern const char *GetGLTargetName( GLenum tgt );
|
||||
extern const char *GetGLBaseFormatName( GLenum baseformat );
|
||||
extern const char *GetGLFormatName( GLenum format );
|
||||
|
||||
extern void* CreateRandomData( ExplicitType type, size_t count, MTdata d );
|
||||
|
||||
extern GLenum GetGLFormat(GLenum internalFormat);
|
||||
extern GLenum GetGLTypeForExplicitType(ExplicitType type);
|
||||
extern size_t GetGLTypeSize(GLenum type);
|
||||
extern ExplicitType GetExplicitTypeForGLType(GLenum type);
|
||||
|
||||
extern GLenum get_base_gl_target( GLenum target );
|
||||
|
||||
extern int init_clgl_ext( void );
|
||||
|
||||
#endif // _helpers_h
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _helpers_h
|
||||
#define _helpers_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if !defined (__APPLE__)
|
||||
#include <CL/cl.h>
|
||||
#include "gl_headers.h"
|
||||
#include <CL/cl_gl.h>
|
||||
#else
|
||||
#include "gl_headers.h"
|
||||
#endif
|
||||
|
||||
#include "../../test_common/harness/errorHelpers.h"
|
||||
#include "../../test_common/harness/kernelHelpers.h"
|
||||
#include "../../test_common/harness/threadTesting.h"
|
||||
#include "../../test_common/harness/typeWrappers.h"
|
||||
#include "../../test_common/harness/conversions.h"
|
||||
#include "../../test_common/harness/mt19937.h"
|
||||
|
||||
typedef cl_mem
|
||||
(CL_API_CALL *clCreateFromGLBuffer_fn)(cl_context context,
|
||||
cl_mem_flags flags,
|
||||
GLuint bufobj,
|
||||
int * errcode_ret);
|
||||
|
||||
typedef cl_mem
|
||||
(CL_API_CALL *clCreateFromGLTexture_fn)(cl_context context ,
|
||||
cl_mem_flags flags ,
|
||||
GLenum target ,
|
||||
GLint miplevel ,
|
||||
GLuint texture ,
|
||||
cl_int * errcode_ret) ;
|
||||
|
||||
typedef cl_mem
|
||||
(CL_API_CALL *clCreateFromGLTexture2D_fn)(cl_context context ,
|
||||
cl_mem_flags flags ,
|
||||
GLenum target ,
|
||||
GLint miplevel ,
|
||||
GLuint texture ,
|
||||
cl_int * errcode_ret) ;
|
||||
|
||||
typedef cl_mem
|
||||
(CL_API_CALL *clCreateFromGLTexture3D_fn)(cl_context context ,
|
||||
cl_mem_flags flags ,
|
||||
GLenum target ,
|
||||
GLint miplevel ,
|
||||
GLuint texture ,
|
||||
cl_int * errcode_ret) ;
|
||||
|
||||
typedef cl_mem
|
||||
(CL_API_CALL *clCreateFromGLRenderbuffer_fn)(cl_context context ,
|
||||
cl_mem_flags flags ,
|
||||
GLuint renderbuffer ,
|
||||
cl_int * errcode_ret) ;
|
||||
|
||||
typedef cl_int
|
||||
(CL_API_CALL *clGetGLObjectInfo_fn)(cl_mem memobj ,
|
||||
cl_gl_object_type * gl_object_type ,
|
||||
GLuint * gl_object_name) ;
|
||||
|
||||
typedef cl_int
|
||||
(CL_API_CALL *clGetGLTextureInfo_fn)(cl_mem memobj ,
|
||||
cl_gl_texture_info param_name ,
|
||||
size_t param_value_size ,
|
||||
void * param_value ,
|
||||
size_t * param_value_size_ret) ;
|
||||
|
||||
typedef cl_int
|
||||
(CL_API_CALL *clEnqueueAcquireGLObjects_fn)(cl_command_queue command_queue ,
|
||||
cl_uint num_objects ,
|
||||
const cl_mem * mem_objects ,
|
||||
cl_uint num_events_in_wait_list ,
|
||||
const cl_event * event_wait_list ,
|
||||
cl_event * event) ;
|
||||
|
||||
typedef cl_int
|
||||
(CL_API_CALL *clEnqueueReleaseGLObjects_fn)(cl_command_queue command_queue ,
|
||||
cl_uint num_objects ,
|
||||
const cl_mem * mem_objects ,
|
||||
cl_uint num_events_in_wait_list ,
|
||||
const cl_event * event_wait_list ,
|
||||
cl_event * event) ;
|
||||
|
||||
|
||||
extern clCreateFromGLBuffer_fn clCreateFromGLBuffer_ptr;
|
||||
extern clCreateFromGLTexture_fn clCreateFromGLTexture_ptr;
|
||||
extern clCreateFromGLTexture2D_fn clCreateFromGLTexture2D_ptr;
|
||||
extern clCreateFromGLTexture3D_fn clCreateFromGLTexture3D_ptr;
|
||||
extern clCreateFromGLRenderbuffer_fn clCreateFromGLRenderbuffer_ptr;
|
||||
extern clGetGLObjectInfo_fn clGetGLObjectInfo_ptr;
|
||||
extern clGetGLTextureInfo_fn clGetGLTextureInfo_ptr;
|
||||
extern clEnqueueAcquireGLObjects_fn clEnqueueAcquireGLObjects_ptr;
|
||||
extern clEnqueueReleaseGLObjects_fn clEnqueueReleaseGLObjects_ptr;
|
||||
|
||||
|
||||
class glBufferWrapper
|
||||
{
|
||||
public:
|
||||
glBufferWrapper() { mBuffer = 0; }
|
||||
glBufferWrapper( GLuint b ) { mBuffer = b; }
|
||||
~glBufferWrapper() { if( mBuffer != 0 ) glDeleteBuffers( 1, &mBuffer ); }
|
||||
|
||||
glBufferWrapper & operator=( const GLuint &rhs ) { mBuffer = rhs; return *this; }
|
||||
operator GLuint() { return mBuffer; }
|
||||
operator GLuint *() { return &mBuffer; }
|
||||
|
||||
GLuint * operator&() { return &mBuffer; }
|
||||
|
||||
bool operator==( GLuint rhs ) { return mBuffer == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
GLuint mBuffer;
|
||||
};
|
||||
|
||||
class glTextureWrapper
|
||||
{
|
||||
public:
|
||||
glTextureWrapper() { mHandle = 0; }
|
||||
glTextureWrapper( GLuint b ) { mHandle = b; }
|
||||
~glTextureWrapper() {
|
||||
if( mHandle != 0 ) glDeleteTextures( 1, &mHandle );
|
||||
}
|
||||
|
||||
glTextureWrapper & operator=( const GLuint &rhs ) { mHandle = rhs; return *this; }
|
||||
operator GLuint() { return mHandle; }
|
||||
operator GLuint *() { return &mHandle; }
|
||||
|
||||
GLuint * operator&() { return &mHandle; }
|
||||
|
||||
bool operator==( GLuint rhs ) { return mHandle == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
// The texture handle.
|
||||
GLuint mHandle;
|
||||
};
|
||||
|
||||
class glRenderbufferWrapper
|
||||
{
|
||||
public:
|
||||
glRenderbufferWrapper() { mBuffer = 0; }
|
||||
glRenderbufferWrapper( GLuint b ) { mBuffer = b; }
|
||||
~glRenderbufferWrapper() { if( mBuffer != 0 ) glDeleteRenderbuffersEXT( 1, &mBuffer ); }
|
||||
|
||||
glRenderbufferWrapper & operator=( const GLuint &rhs ) { mBuffer = rhs; return *this; }
|
||||
operator GLuint() { return mBuffer; }
|
||||
operator GLuint *() { return &mBuffer; }
|
||||
|
||||
GLuint * operator&() { return &mBuffer; }
|
||||
|
||||
bool operator==( GLuint rhs ) { return mBuffer == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
GLuint mBuffer;
|
||||
};
|
||||
|
||||
class glFramebufferWrapper
|
||||
{
|
||||
public:
|
||||
glFramebufferWrapper() { mBuffer = 0; }
|
||||
glFramebufferWrapper( GLuint b ) { mBuffer = b; }
|
||||
~glFramebufferWrapper() { if( mBuffer != 0 ) glDeleteFramebuffersEXT( 1, &mBuffer ); }
|
||||
|
||||
glFramebufferWrapper & operator=( const GLuint &rhs ) { mBuffer = rhs; return *this; }
|
||||
operator GLuint() { return mBuffer; }
|
||||
operator GLuint *() { return &mBuffer; }
|
||||
|
||||
GLuint * operator&() { return &mBuffer; }
|
||||
|
||||
bool operator==( GLuint rhs ) { return mBuffer == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
GLuint mBuffer;
|
||||
};
|
||||
|
||||
|
||||
// Helper functions (defined in helpers.cpp)
|
||||
|
||||
extern void * CreateGLTexture1DArray( size_t width, size_t length,
|
||||
GLenum target, GLenum glFormat, GLenum internalFormat, GLenum glType,
|
||||
ExplicitType type, GLuint *outTextureID, int *outError,
|
||||
bool allocateMem, MTdata d);
|
||||
|
||||
extern void * CreateGLTexture2DArray( size_t width, size_t height, size_t length,
|
||||
GLenum target, GLenum glFormat, GLenum internalFormat, GLenum glType,
|
||||
ExplicitType type, GLuint *outTextureID, int *outError,
|
||||
bool allocateMem, MTdata d);
|
||||
|
||||
extern void * CreateGLTextureBuffer( size_t width,
|
||||
GLenum target, GLenum glFormat, GLenum internalFormat, GLenum glType,
|
||||
ExplicitType type, GLuint *outTex, GLuint *outBuf, int *outError,
|
||||
bool allocateMem, MTdata d);
|
||||
|
||||
extern void * CreateGLTexture1D(size_t width,
|
||||
GLenum target, GLenum glFormat,
|
||||
GLenum internalFormat, GLenum glType,
|
||||
ExplicitType type, GLuint *outTextureID,
|
||||
int *outError, bool allocateMem, MTdata d );
|
||||
|
||||
extern void * CreateGLTexture2D( size_t width, size_t height,
|
||||
GLenum target, GLenum glFormat,
|
||||
GLenum internalFormat, GLenum glType,
|
||||
ExplicitType type, GLuint *outTextureID,
|
||||
int *outError, bool allocateMem, MTdata d );
|
||||
|
||||
|
||||
extern void * CreateGLTexture3D( size_t width, size_t height, size_t depth,
|
||||
GLenum target, GLenum glFormat,
|
||||
GLenum internalFormat, GLenum glType,
|
||||
ExplicitType type, GLuint *outTextureID,
|
||||
int *outError, MTdata d, bool allocateMem = true );
|
||||
|
||||
extern void * ReadGLTexture( GLenum glTarget, GLuint glTexture, GLuint glBuf, GLint width,
|
||||
GLenum glFormat, GLenum glInternalFormat,
|
||||
GLenum glType, ExplicitType typeToReadAs,
|
||||
size_t outWidth, size_t outHeight );
|
||||
|
||||
extern int CreateGLRenderbufferRaw( GLsizei width, GLsizei height,
|
||||
GLenum target, GLenum glFormat,
|
||||
GLenum internalFormat, GLenum glType,
|
||||
GLuint *outFramebuffer,
|
||||
GLuint *outRenderbuffer );
|
||||
|
||||
extern void * CreateGLRenderbuffer( GLsizei width, GLsizei height,
|
||||
GLenum target, GLenum glFormat,
|
||||
GLenum internalFormat, GLenum glType,
|
||||
ExplicitType type,
|
||||
GLuint *outFramebuffer,
|
||||
GLuint *outRenderbuffer,
|
||||
int *outError, MTdata d, bool allocateMem );
|
||||
|
||||
extern void * ReadGLRenderbuffer( GLuint glFramebuffer, GLuint glRenderbuffer,
|
||||
GLenum attachment, GLenum glFormat,
|
||||
GLenum glInternalFormat, GLenum glType,
|
||||
ExplicitType typeToReadAs,
|
||||
size_t outWidth, size_t outHeight );
|
||||
|
||||
extern void DumpGLBuffer(GLenum type, size_t width, size_t height, void* buffer);
|
||||
extern const char *GetGLTypeName( GLenum type );
|
||||
extern const char *GetGLAttachmentName( GLenum att );
|
||||
extern const char *GetGLTargetName( GLenum tgt );
|
||||
extern const char *GetGLBaseFormatName( GLenum baseformat );
|
||||
extern const char *GetGLFormatName( GLenum format );
|
||||
|
||||
extern void* CreateRandomData( ExplicitType type, size_t count, MTdata d );
|
||||
|
||||
extern GLenum GetGLFormat(GLenum internalFormat);
|
||||
extern GLenum GetGLTypeForExplicitType(ExplicitType type);
|
||||
extern size_t GetGLTypeSize(GLenum type);
|
||||
extern ExplicitType GetExplicitTypeForGLType(GLenum type);
|
||||
|
||||
extern GLenum get_base_gl_target( GLenum target );
|
||||
|
||||
extern int init_clgl_ext( void );
|
||||
|
||||
#endif // _helpers_h
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,48 +1,48 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _setup_h
|
||||
#define _setup_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "gl_headers.h"
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/opencl.h>
|
||||
#else
|
||||
#include <CL/opencl.h>
|
||||
#endif
|
||||
|
||||
|
||||
// Note: the idea here is to have every platform define their own setup.cpp file that implements a GLEnvironment
|
||||
// subclass internally, then return it as a definition for GLEnvironment::Create
|
||||
|
||||
class GLEnvironment
|
||||
{
|
||||
public:
|
||||
GLEnvironment() {}
|
||||
virtual ~GLEnvironment() {}
|
||||
|
||||
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 );
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // _setup_h
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _setup_h
|
||||
#define _setup_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "gl_headers.h"
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/opencl.h>
|
||||
#else
|
||||
#include <CL/opencl.h>
|
||||
#endif
|
||||
|
||||
|
||||
// Note: the idea here is to have every platform define their own setup.cpp file that implements a GLEnvironment
|
||||
// subclass internally, then return it as a definition for GLEnvironment::Create
|
||||
|
||||
class GLEnvironment
|
||||
{
|
||||
public:
|
||||
GLEnvironment() {}
|
||||
virtual ~GLEnvironment() {}
|
||||
|
||||
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 );
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // _setup_h
|
||||
|
||||
@@ -1,156 +1,156 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "setup.h"
|
||||
#include "../../test_common/harness/errorHelpers.h"
|
||||
#include <OpenGL/CGLDevice.h>
|
||||
|
||||
class OSXGLEnvironment : public GLEnvironment
|
||||
{
|
||||
public:
|
||||
OSXGLEnvironment()
|
||||
{
|
||||
mCGLContext = NULL;
|
||||
}
|
||||
|
||||
virtual int Init( int *argc, char **argv, int use_opengl_32 )
|
||||
{
|
||||
if (!use_opengl_32) {
|
||||
|
||||
// Create a GLUT window to render into
|
||||
glutInit( argc, argv );
|
||||
glutInitWindowSize( 512, 512 );
|
||||
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
|
||||
glutCreateWindow( "OpenCL <-> OpenGL Test" );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
virtual cl_context CreateCLContext( void )
|
||||
{
|
||||
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 };
|
||||
cl_context context = clCreateContext(properties, 0, 0, 0, 0, &error);
|
||||
if (error) {
|
||||
print_error(error, "clCreateContext failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Verify that all devices in the context support the required extension
|
||||
cl_device_id devices[64];
|
||||
size_t size_out;
|
||||
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(devices), devices, &size_out);
|
||||
if (error) {
|
||||
print_error(error, "clGetContextInfo failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char extensions[8192];
|
||||
for (int i=0; i<(int)(size_out/sizeof(cl_device_id)); i++) {
|
||||
error = clGetDeviceInfo(devices[i], CL_DEVICE_EXTENSIONS, sizeof(extensions), extensions, NULL);
|
||||
if (error) {
|
||||
print_error(error, "clGetDeviceInfo failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strstr(extensions, "cl_APPLE_gl_sharing") == NULL) {
|
||||
log_error("Device %d does not supporte required extension cl_APPLE_gl_sharing.\n", i);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
virtual int SupportsCLGLInterop( cl_device_type device_type )
|
||||
{
|
||||
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);
|
||||
if (error) {
|
||||
print_error(error, "clGetDeviceIDs failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char extensions[8192];
|
||||
for (int i=0; i<(int)num_of_devices; i++) {
|
||||
error = clGetDeviceInfo(devices[i], CL_DEVICE_EXTENSIONS, sizeof(extensions), extensions, NULL);
|
||||
if (error) {
|
||||
print_error(error, "clGetDeviceInfo failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strstr(extensions, "cl_APPLE_gl_sharing") == NULL) {
|
||||
log_info("Device %d of %d does not support required extension cl_APPLE_gl_sharing.\n", i, num_of_devices);
|
||||
} else {
|
||||
log_info("Device %d of %d does support required extension cl_APPLE_gl_sharing.\n", i, num_of_devices);
|
||||
found_valid_device = 1;
|
||||
}
|
||||
}
|
||||
return found_valid_device;
|
||||
}
|
||||
|
||||
virtual ~OSXGLEnvironment()
|
||||
{
|
||||
CGLDestroyContext( mCGLContext );
|
||||
}
|
||||
|
||||
CGLContextObj mCGLContext;
|
||||
|
||||
};
|
||||
|
||||
GLEnvironment * GLEnvironment::Instance( void )
|
||||
{
|
||||
static OSXGLEnvironment * env = NULL;
|
||||
if( env == NULL )
|
||||
env = new OSXGLEnvironment();
|
||||
return env;
|
||||
}
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "setup.h"
|
||||
#include "../../test_common/harness/errorHelpers.h"
|
||||
#include <OpenGL/CGLDevice.h>
|
||||
|
||||
class OSXGLEnvironment : public GLEnvironment
|
||||
{
|
||||
public:
|
||||
OSXGLEnvironment()
|
||||
{
|
||||
mCGLContext = NULL;
|
||||
}
|
||||
|
||||
virtual int Init( int *argc, char **argv, int use_opengl_32 )
|
||||
{
|
||||
if (!use_opengl_32) {
|
||||
|
||||
// Create a GLUT window to render into
|
||||
glutInit( argc, argv );
|
||||
glutInitWindowSize( 512, 512 );
|
||||
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
|
||||
glutCreateWindow( "OpenCL <-> OpenGL Test" );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
virtual cl_context CreateCLContext( void )
|
||||
{
|
||||
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 };
|
||||
cl_context context = clCreateContext(properties, 0, 0, 0, 0, &error);
|
||||
if (error) {
|
||||
print_error(error, "clCreateContext failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Verify that all devices in the context support the required extension
|
||||
cl_device_id devices[64];
|
||||
size_t size_out;
|
||||
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(devices), devices, &size_out);
|
||||
if (error) {
|
||||
print_error(error, "clGetContextInfo failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char extensions[8192];
|
||||
for (int i=0; i<(int)(size_out/sizeof(cl_device_id)); i++) {
|
||||
error = clGetDeviceInfo(devices[i], CL_DEVICE_EXTENSIONS, sizeof(extensions), extensions, NULL);
|
||||
if (error) {
|
||||
print_error(error, "clGetDeviceInfo failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strstr(extensions, "cl_APPLE_gl_sharing") == NULL) {
|
||||
log_error("Device %d does not supporte required extension cl_APPLE_gl_sharing.\n", i);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
virtual int SupportsCLGLInterop( cl_device_type device_type )
|
||||
{
|
||||
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);
|
||||
if (error) {
|
||||
print_error(error, "clGetDeviceIDs failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char extensions[8192];
|
||||
for (int i=0; i<(int)num_of_devices; i++) {
|
||||
error = clGetDeviceInfo(devices[i], CL_DEVICE_EXTENSIONS, sizeof(extensions), extensions, NULL);
|
||||
if (error) {
|
||||
print_error(error, "clGetDeviceInfo failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strstr(extensions, "cl_APPLE_gl_sharing") == NULL) {
|
||||
log_info("Device %d of %d does not support required extension cl_APPLE_gl_sharing.\n", i, num_of_devices);
|
||||
} else {
|
||||
log_info("Device %d of %d does support required extension cl_APPLE_gl_sharing.\n", i, num_of_devices);
|
||||
found_valid_device = 1;
|
||||
}
|
||||
}
|
||||
return found_valid_device;
|
||||
}
|
||||
|
||||
virtual ~OSXGLEnvironment()
|
||||
{
|
||||
CGLDestroyContext( mCGLContext );
|
||||
}
|
||||
|
||||
CGLContextObj mCGLContext;
|
||||
|
||||
};
|
||||
|
||||
GLEnvironment * GLEnvironment::Instance( void )
|
||||
{
|
||||
static OSXGLEnvironment * env = NULL;
|
||||
if( env == NULL )
|
||||
env = new OSXGLEnvironment();
|
||||
return env;
|
||||
}
|
||||
|
||||
@@ -1,204 +1,204 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
|
||||
#include "setup.h"
|
||||
#include "testBase.h"
|
||||
#include "../../test_common/harness/errorHelpers.h"
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glut.h>
|
||||
#include <GL/glext.h>
|
||||
#include <GL/glut.h>
|
||||
#include <CL/cl_ext.h>
|
||||
|
||||
typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetGLContextInfoKHR_fn)(
|
||||
const cl_context_properties *properties,
|
||||
cl_gl_context_info param_name,
|
||||
size_t param_value_size,
|
||||
void *param_value,
|
||||
size_t *param_value_size_ret);
|
||||
|
||||
// Rename references to this dynamically linked function to avoid
|
||||
// collision with static link version
|
||||
#define clGetGLContextInfoKHR clGetGLContextInfoKHR_proc
|
||||
static clGetGLContextInfoKHR_fn clGetGLContextInfoKHR;
|
||||
|
||||
#define MAX_DEVICES 32
|
||||
|
||||
class WGLEnvironment : public GLEnvironment
|
||||
{
|
||||
private:
|
||||
cl_device_id m_devices[MAX_DEVICES];
|
||||
int m_device_count;
|
||||
cl_platform_id m_platform;
|
||||
|
||||
public:
|
||||
WGLEnvironment()
|
||||
{
|
||||
m_device_count = 0;
|
||||
m_platform = 0;
|
||||
|
||||
}
|
||||
virtual int Init( int *argc, char **argv, int use_opengl_32 )
|
||||
{
|
||||
// Create a GLUT window to render into
|
||||
glutInit( argc, argv );
|
||||
glutInitWindowSize( 512, 512 );
|
||||
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
|
||||
glutCreateWindow( "OpenCL <-> OpenGL Test" );
|
||||
glewInit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual cl_context CreateCLContext( void )
|
||||
{
|
||||
HGLRC hGLRC = wglGetCurrentContext();
|
||||
HDC 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,
|
||||
0
|
||||
};
|
||||
cl_device_id devices[MAX_DEVICES];
|
||||
size_t dev_size;
|
||||
cl_int status;
|
||||
|
||||
if (!hGLRC || !hDC) {
|
||||
print_error(CL_INVALID_CONTEXT, "No GL context bound");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!clGetGLContextInfoKHR) {
|
||||
// As OpenCL for the platforms. Warn if more than one platform found,
|
||||
// since this might not be the platform we want. By default, we simply
|
||||
// use the first returned platform.
|
||||
|
||||
cl_uint nplatforms;
|
||||
cl_platform_id platform;
|
||||
clGetPlatformIDs(0, NULL, &nplatforms);
|
||||
clGetPlatformIDs(1, &platform, NULL);
|
||||
|
||||
if (nplatforms > 1) {
|
||||
log_info("clGetPlatformIDs returned multiple values. This is not "
|
||||
"an error, but might result in obtaining incorrect function "
|
||||
"pointers if you do not want the first returned platform.\n");
|
||||
|
||||
// Show them the platform name, in case it is a problem.
|
||||
|
||||
size_t size;
|
||||
char *name;
|
||||
|
||||
clGetPlatformInfo(platform, CL_PLATFORM_NAME, 0, NULL, &size);
|
||||
name = (char*)malloc(size);
|
||||
clGetPlatformInfo(platform, CL_PLATFORM_NAME, size, name, NULL);
|
||||
|
||||
log_info("Using platform with name: %s \n", name);
|
||||
free(name);
|
||||
}
|
||||
|
||||
clGetGLContextInfoKHR = (clGetGLContextInfoKHR_fn) clGetExtensionFunctionAddressForPlatform(platform, "clGetGLContextInfoKHR");
|
||||
if (!clGetGLContextInfoKHR) {
|
||||
print_error(CL_INVALID_PLATFORM, "Failed to query proc address for clGetGLContextInfoKHR");
|
||||
}
|
||||
}
|
||||
|
||||
status = clGetGLContextInfoKHR(properties,
|
||||
CL_DEVICES_FOR_GL_CONTEXT_KHR,
|
||||
sizeof(devices),
|
||||
devices,
|
||||
&dev_size);
|
||||
if (status != CL_SUCCESS) {
|
||||
print_error(status, "clGetGLContextInfoKHR failed");
|
||||
return 0;
|
||||
}
|
||||
dev_size /= sizeof(cl_device_id);
|
||||
log_info("GL context supports %d compute devices\n", dev_size);
|
||||
|
||||
status = clGetGLContextInfoKHR(properties,
|
||||
CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR,
|
||||
sizeof(devices),
|
||||
devices,
|
||||
&dev_size);
|
||||
if (status != CL_SUCCESS) {
|
||||
print_error(status, "clGetGLContextInfoKHR failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cl_device_id ctxDevice = m_devices[0];
|
||||
if (dev_size > 0) {
|
||||
log_info("GL context current device: 0x%x\n", devices[0]);
|
||||
for (int i = 0; i < m_device_count; i++) {
|
||||
if (m_devices[i] == devices[0]) {
|
||||
ctxDevice = devices[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log_info("GL context current device is not a CL device, using device %d.\n", ctxDevice);
|
||||
}
|
||||
|
||||
return clCreateContext(properties, 1, &ctxDevice, NULL, NULL, &status);
|
||||
}
|
||||
|
||||
virtual int SupportsCLGLInterop( cl_device_type device_type )
|
||||
{
|
||||
cl_device_id devices[MAX_DEVICES];
|
||||
cl_uint num_of_devices;
|
||||
int error;
|
||||
error = clGetPlatformIDs(1, &m_platform, NULL);
|
||||
if (error) {
|
||||
print_error(error, "clGetPlatformIDs failed");
|
||||
return -1;
|
||||
}
|
||||
error = clGetDeviceIDs(m_platform, device_type, MAX_DEVICES, devices, &num_of_devices);
|
||||
if (error) {
|
||||
print_error(error, "clGetDeviceIDs failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check all devices, search for one that supports cl_khr_gl_sharing
|
||||
char extensions[8192];
|
||||
for (int i=0; i<(int)num_of_devices; i++) {
|
||||
error = clGetDeviceInfo(devices[i], CL_DEVICE_EXTENSIONS, sizeof(extensions), extensions, NULL);
|
||||
if (error) {
|
||||
print_error(error, "clGetDeviceInfo failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strstr(extensions, "cl_khr_gl_sharing") == NULL) {
|
||||
log_info("Device %d of %d does not support required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
|
||||
} else {
|
||||
log_info("Device %d of %d supports required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
|
||||
m_devices[m_device_count++] = devices[i];
|
||||
}
|
||||
}
|
||||
return m_device_count > 0;
|
||||
}
|
||||
|
||||
virtual ~WGLEnvironment()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
GLEnvironment * GLEnvironment::Instance( void )
|
||||
{
|
||||
static WGLEnvironment * env = NULL;
|
||||
if( env == NULL )
|
||||
env = new WGLEnvironment();
|
||||
return env;
|
||||
}
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
|
||||
#include "setup.h"
|
||||
#include "testBase.h"
|
||||
#include "../../test_common/harness/errorHelpers.h"
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glut.h>
|
||||
#include <GL/glext.h>
|
||||
#include <GL/glut.h>
|
||||
#include <CL/cl_ext.h>
|
||||
|
||||
typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetGLContextInfoKHR_fn)(
|
||||
const cl_context_properties *properties,
|
||||
cl_gl_context_info param_name,
|
||||
size_t param_value_size,
|
||||
void *param_value,
|
||||
size_t *param_value_size_ret);
|
||||
|
||||
// Rename references to this dynamically linked function to avoid
|
||||
// collision with static link version
|
||||
#define clGetGLContextInfoKHR clGetGLContextInfoKHR_proc
|
||||
static clGetGLContextInfoKHR_fn clGetGLContextInfoKHR;
|
||||
|
||||
#define MAX_DEVICES 32
|
||||
|
||||
class WGLEnvironment : public GLEnvironment
|
||||
{
|
||||
private:
|
||||
cl_device_id m_devices[MAX_DEVICES];
|
||||
int m_device_count;
|
||||
cl_platform_id m_platform;
|
||||
|
||||
public:
|
||||
WGLEnvironment()
|
||||
{
|
||||
m_device_count = 0;
|
||||
m_platform = 0;
|
||||
|
||||
}
|
||||
virtual int Init( int *argc, char **argv, int use_opengl_32 )
|
||||
{
|
||||
// Create a GLUT window to render into
|
||||
glutInit( argc, argv );
|
||||
glutInitWindowSize( 512, 512 );
|
||||
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
|
||||
glutCreateWindow( "OpenCL <-> OpenGL Test" );
|
||||
glewInit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual cl_context CreateCLContext( void )
|
||||
{
|
||||
HGLRC hGLRC = wglGetCurrentContext();
|
||||
HDC 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,
|
||||
0
|
||||
};
|
||||
cl_device_id devices[MAX_DEVICES];
|
||||
size_t dev_size;
|
||||
cl_int status;
|
||||
|
||||
if (!hGLRC || !hDC) {
|
||||
print_error(CL_INVALID_CONTEXT, "No GL context bound");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!clGetGLContextInfoKHR) {
|
||||
// As OpenCL for the platforms. Warn if more than one platform found,
|
||||
// since this might not be the platform we want. By default, we simply
|
||||
// use the first returned platform.
|
||||
|
||||
cl_uint nplatforms;
|
||||
cl_platform_id platform;
|
||||
clGetPlatformIDs(0, NULL, &nplatforms);
|
||||
clGetPlatformIDs(1, &platform, NULL);
|
||||
|
||||
if (nplatforms > 1) {
|
||||
log_info("clGetPlatformIDs returned multiple values. This is not "
|
||||
"an error, but might result in obtaining incorrect function "
|
||||
"pointers if you do not want the first returned platform.\n");
|
||||
|
||||
// Show them the platform name, in case it is a problem.
|
||||
|
||||
size_t size;
|
||||
char *name;
|
||||
|
||||
clGetPlatformInfo(platform, CL_PLATFORM_NAME, 0, NULL, &size);
|
||||
name = (char*)malloc(size);
|
||||
clGetPlatformInfo(platform, CL_PLATFORM_NAME, size, name, NULL);
|
||||
|
||||
log_info("Using platform with name: %s \n", name);
|
||||
free(name);
|
||||
}
|
||||
|
||||
clGetGLContextInfoKHR = (clGetGLContextInfoKHR_fn) clGetExtensionFunctionAddressForPlatform(platform, "clGetGLContextInfoKHR");
|
||||
if (!clGetGLContextInfoKHR) {
|
||||
print_error(CL_INVALID_PLATFORM, "Failed to query proc address for clGetGLContextInfoKHR");
|
||||
}
|
||||
}
|
||||
|
||||
status = clGetGLContextInfoKHR(properties,
|
||||
CL_DEVICES_FOR_GL_CONTEXT_KHR,
|
||||
sizeof(devices),
|
||||
devices,
|
||||
&dev_size);
|
||||
if (status != CL_SUCCESS) {
|
||||
print_error(status, "clGetGLContextInfoKHR failed");
|
||||
return 0;
|
||||
}
|
||||
dev_size /= sizeof(cl_device_id);
|
||||
log_info("GL context supports %d compute devices\n", dev_size);
|
||||
|
||||
status = clGetGLContextInfoKHR(properties,
|
||||
CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR,
|
||||
sizeof(devices),
|
||||
devices,
|
||||
&dev_size);
|
||||
if (status != CL_SUCCESS) {
|
||||
print_error(status, "clGetGLContextInfoKHR failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cl_device_id ctxDevice = m_devices[0];
|
||||
if (dev_size > 0) {
|
||||
log_info("GL context current device: 0x%x\n", devices[0]);
|
||||
for (int i = 0; i < m_device_count; i++) {
|
||||
if (m_devices[i] == devices[0]) {
|
||||
ctxDevice = devices[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log_info("GL context current device is not a CL device, using device %d.\n", ctxDevice);
|
||||
}
|
||||
|
||||
return clCreateContext(properties, 1, &ctxDevice, NULL, NULL, &status);
|
||||
}
|
||||
|
||||
virtual int SupportsCLGLInterop( cl_device_type device_type )
|
||||
{
|
||||
cl_device_id devices[MAX_DEVICES];
|
||||
cl_uint num_of_devices;
|
||||
int error;
|
||||
error = clGetPlatformIDs(1, &m_platform, NULL);
|
||||
if (error) {
|
||||
print_error(error, "clGetPlatformIDs failed");
|
||||
return -1;
|
||||
}
|
||||
error = clGetDeviceIDs(m_platform, device_type, MAX_DEVICES, devices, &num_of_devices);
|
||||
if (error) {
|
||||
print_error(error, "clGetDeviceIDs failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check all devices, search for one that supports cl_khr_gl_sharing
|
||||
char extensions[8192];
|
||||
for (int i=0; i<(int)num_of_devices; i++) {
|
||||
error = clGetDeviceInfo(devices[i], CL_DEVICE_EXTENSIONS, sizeof(extensions), extensions, NULL);
|
||||
if (error) {
|
||||
print_error(error, "clGetDeviceInfo failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strstr(extensions, "cl_khr_gl_sharing") == NULL) {
|
||||
log_info("Device %d of %d does not support required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
|
||||
} else {
|
||||
log_info("Device %d of %d supports required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
|
||||
m_devices[m_device_count++] = devices[i];
|
||||
}
|
||||
}
|
||||
return m_device_count > 0;
|
||||
}
|
||||
|
||||
virtual ~WGLEnvironment()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
GLEnvironment * GLEnvironment::Instance( void )
|
||||
{
|
||||
static WGLEnvironment * env = NULL;
|
||||
if( env == NULL )
|
||||
env = new WGLEnvironment();
|
||||
return env;
|
||||
}
|
||||
|
||||
@@ -1,122 +1,122 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
|
||||
#include "setup.h"
|
||||
#include "testBase.h"
|
||||
#include "../../test_common/harness/errorHelpers.h"
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glut.h>
|
||||
#include <GL/glext.h>
|
||||
#include <GL/freeglut.h>
|
||||
#include <GL/glx.h>
|
||||
#include <CL/cl_ext.h>
|
||||
|
||||
class X11GLEnvironment : public GLEnvironment
|
||||
{
|
||||
private:
|
||||
cl_device_id m_devices[64];
|
||||
cl_uint m_device_count;
|
||||
|
||||
public:
|
||||
X11GLEnvironment()
|
||||
{
|
||||
m_device_count = 0;
|
||||
}
|
||||
virtual int Init( int *argc, char **argv, int use_opencl_32 )
|
||||
{
|
||||
// Create a GLUT window to render into
|
||||
glutInit( argc, argv );
|
||||
glutInitWindowSize( 512, 512 );
|
||||
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
|
||||
glutCreateWindow( "OpenCL <-> OpenGL Test" );
|
||||
glewInit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual cl_context CreateCLContext( void )
|
||||
{
|
||||
GLXContext context = glXGetCurrentContext();
|
||||
Display *dpy = glXGetCurrentDisplay();
|
||||
|
||||
cl_context_properties properties[] = {
|
||||
CL_GL_CONTEXT_KHR, (cl_context_properties) context,
|
||||
CL_GLX_DISPLAY_KHR, (cl_context_properties) dpy,
|
||||
0
|
||||
};
|
||||
cl_int status;
|
||||
|
||||
if (!context || !dpy) {
|
||||
print_error(CL_INVALID_CONTEXT, "No GL context bound");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return clCreateContext(properties, 1, m_devices, NULL, NULL, &status);
|
||||
}
|
||||
|
||||
virtual int SupportsCLGLInterop( cl_device_type device_type )
|
||||
{
|
||||
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);
|
||||
if (error) {
|
||||
print_error(error, "clGetPlatformIDs failed");
|
||||
return -1;
|
||||
}
|
||||
error = clGetDeviceIDs(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;
|
||||
if (error) {
|
||||
print_error(error, "clGetDeviceIDs failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char extensions[8192];
|
||||
for (int i=0; i<(int)num_of_devices; i++) {
|
||||
error = clGetDeviceInfo(devices[i], CL_DEVICE_EXTENSIONS, sizeof(extensions), extensions, NULL);
|
||||
if (error) {
|
||||
print_error(error, "clGetDeviceInfo failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strstr(extensions, "cl_khr_gl_sharing ") == NULL) {
|
||||
log_info("Device %d of %d does not support required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
|
||||
} else {
|
||||
log_info("Device %d of %d supports required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
|
||||
found_valid_device = 1;
|
||||
m_devices[m_device_count++] = devices[i];
|
||||
}
|
||||
}
|
||||
return found_valid_device;
|
||||
}
|
||||
|
||||
virtual ~X11GLEnvironment()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
GLEnvironment * GLEnvironment::Instance( void )
|
||||
{
|
||||
static X11GLEnvironment * env = NULL;
|
||||
if( env == NULL )
|
||||
env = new X11GLEnvironment();
|
||||
return env;
|
||||
}
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
|
||||
#include "setup.h"
|
||||
#include "testBase.h"
|
||||
#include "../../test_common/harness/errorHelpers.h"
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glut.h>
|
||||
#include <GL/glext.h>
|
||||
#include <GL/freeglut.h>
|
||||
#include <GL/glx.h>
|
||||
#include <CL/cl_ext.h>
|
||||
|
||||
class X11GLEnvironment : public GLEnvironment
|
||||
{
|
||||
private:
|
||||
cl_device_id m_devices[64];
|
||||
cl_uint m_device_count;
|
||||
|
||||
public:
|
||||
X11GLEnvironment()
|
||||
{
|
||||
m_device_count = 0;
|
||||
}
|
||||
virtual int Init( int *argc, char **argv, int use_opencl_32 )
|
||||
{
|
||||
// Create a GLUT window to render into
|
||||
glutInit( argc, argv );
|
||||
glutInitWindowSize( 512, 512 );
|
||||
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
|
||||
glutCreateWindow( "OpenCL <-> OpenGL Test" );
|
||||
glewInit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual cl_context CreateCLContext( void )
|
||||
{
|
||||
GLXContext context = glXGetCurrentContext();
|
||||
Display *dpy = glXGetCurrentDisplay();
|
||||
|
||||
cl_context_properties properties[] = {
|
||||
CL_GL_CONTEXT_KHR, (cl_context_properties) context,
|
||||
CL_GLX_DISPLAY_KHR, (cl_context_properties) dpy,
|
||||
0
|
||||
};
|
||||
cl_int status;
|
||||
|
||||
if (!context || !dpy) {
|
||||
print_error(CL_INVALID_CONTEXT, "No GL context bound");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return clCreateContext(properties, 1, m_devices, NULL, NULL, &status);
|
||||
}
|
||||
|
||||
virtual int SupportsCLGLInterop( cl_device_type device_type )
|
||||
{
|
||||
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);
|
||||
if (error) {
|
||||
print_error(error, "clGetPlatformIDs failed");
|
||||
return -1;
|
||||
}
|
||||
error = clGetDeviceIDs(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;
|
||||
if (error) {
|
||||
print_error(error, "clGetDeviceIDs failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char extensions[8192];
|
||||
for (int i=0; i<(int)num_of_devices; i++) {
|
||||
error = clGetDeviceInfo(devices[i], CL_DEVICE_EXTENSIONS, sizeof(extensions), extensions, NULL);
|
||||
if (error) {
|
||||
print_error(error, "clGetDeviceInfo failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strstr(extensions, "cl_khr_gl_sharing ") == NULL) {
|
||||
log_info("Device %d of %d does not support required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
|
||||
} else {
|
||||
log_info("Device %d of %d supports required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
|
||||
found_valid_device = 1;
|
||||
m_devices[m_device_count++] = devices[i];
|
||||
}
|
||||
}
|
||||
return found_valid_device;
|
||||
}
|
||||
|
||||
virtual ~X11GLEnvironment()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
GLEnvironment * GLEnvironment::Instance( void )
|
||||
{
|
||||
static X11GLEnvironment * env = NULL;
|
||||
if( env == NULL )
|
||||
env = new X11GLEnvironment();
|
||||
return env;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
project
|
||||
: requirements <include>.
|
||||
<toolset>gcc:<cflags>"-xc++"
|
||||
<toolset>msvc:<cflags>"/TP"
|
||||
<warnings-as-errors>off
|
||||
: usage-requirements <include>.
|
||||
;
|
||||
|
||||
local harness.objs ;
|
||||
for source in [ glob *.c *.cpp ]
|
||||
{
|
||||
harness.objs += [ obj $(source:B).obj : $(source) ] ;
|
||||
}
|
||||
|
||||
alias harness : $(harness.objs)
|
||||
: <use>/Runtime//OpenCL.lib :
|
||||
: <library>/Runtime//OpenCL.lib
|
||||
;
|
||||
project
|
||||
: requirements <include>.
|
||||
<toolset>gcc:<cflags>"-xc++"
|
||||
<toolset>msvc:<cflags>"/TP"
|
||||
<warnings-as-errors>off
|
||||
: usage-requirements <include>.
|
||||
;
|
||||
|
||||
local harness.objs ;
|
||||
for source in [ glob *.c *.cpp ]
|
||||
{
|
||||
harness.objs += [ obj $(source:B).obj : $(source) ] ;
|
||||
}
|
||||
|
||||
alias harness : $(harness.objs)
|
||||
: <use>/Runtime//OpenCL.lib :
|
||||
: <library>/Runtime//OpenCL.lib
|
||||
;
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
ifdef BUILD_WITH_ATF
|
||||
ATF = -framework ATF
|
||||
USE_ATF = -DUSE_ATF
|
||||
endif
|
||||
|
||||
SRCS = conversions.c \
|
||||
errorHelpers.c \
|
||||
genericThread.cpp \
|
||||
imageHelpers.cpp \
|
||||
kernelHelpers.c \
|
||||
mt19937.c \
|
||||
rounding_mode.c \
|
||||
testHarness.c \
|
||||
testHarness.cpp \
|
||||
ThreadPool.c \
|
||||
threadTesting.c \
|
||||
typeWrappers.cpp
|
||||
|
||||
DEFINES = DONT_TEST_GARBAGE_POINTERS
|
||||
|
||||
SOURCES = $(abspath $(SRCS))
|
||||
LIBPATH += -L/System/Library/Frameworks/OpenCL.framework/Libraries
|
||||
LIBPATH += -L.
|
||||
HEADERS =
|
||||
INCLUDE =
|
||||
COMPILERFLAGS = -c -Wall -g -Wshorten-64-to-32
|
||||
CC = c++
|
||||
CFLAGS = $(COMPILERFLAGS) ${RC_CFLAGS} ${USE_ATF} $(DEFINES:%=-D%) $(INCLUDE)
|
||||
CXXFLAGS = $(COMPILERFLAGS) ${RC_CFLAGS} ${USE_ATF} $(DEFINES:%=-D%) $(INCLUDE)
|
||||
LIBRARIES = -framework OpenCL -framework OpenGL -framework GLUT -framework AppKit ${ATF}
|
||||
|
||||
OBJECTS := ${SOURCES:.c=.o}
|
||||
OBJECTS := ${OBJECTS:.cpp=.o}
|
||||
|
||||
all: $(OBJECTS)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS)
|
||||
|
||||
.DEFAULT:
|
||||
@echo The target \"$@\" does not exist in Makefile.
|
||||
ifdef BUILD_WITH_ATF
|
||||
ATF = -framework ATF
|
||||
USE_ATF = -DUSE_ATF
|
||||
endif
|
||||
|
||||
SRCS = conversions.c \
|
||||
errorHelpers.c \
|
||||
genericThread.cpp \
|
||||
imageHelpers.cpp \
|
||||
kernelHelpers.c \
|
||||
mt19937.c \
|
||||
rounding_mode.c \
|
||||
testHarness.c \
|
||||
testHarness.cpp \
|
||||
ThreadPool.c \
|
||||
threadTesting.c \
|
||||
typeWrappers.cpp
|
||||
|
||||
DEFINES = DONT_TEST_GARBAGE_POINTERS
|
||||
|
||||
SOURCES = $(abspath $(SRCS))
|
||||
LIBPATH += -L/System/Library/Frameworks/OpenCL.framework/Libraries
|
||||
LIBPATH += -L.
|
||||
HEADERS =
|
||||
INCLUDE =
|
||||
COMPILERFLAGS = -c -Wall -g -Wshorten-64-to-32
|
||||
CC = c++
|
||||
CFLAGS = $(COMPILERFLAGS) ${RC_CFLAGS} ${USE_ATF} $(DEFINES:%=-D%) $(INCLUDE)
|
||||
CXXFLAGS = $(COMPILERFLAGS) ${RC_CFLAGS} ${USE_ATF} $(DEFINES:%=-D%) $(INCLUDE)
|
||||
LIBRARIES = -framework OpenCL -framework OpenGL -framework GLUT -framework AppKit ${ATF}
|
||||
|
||||
OBJECTS := ${SOURCES:.c=.o}
|
||||
OBJECTS := ${OBJECTS:.cpp=.o}
|
||||
|
||||
all: $(OBJECTS)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS)
|
||||
|
||||
.DEFAULT:
|
||||
@echo The target \"$@\" does not exist in Makefile.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,76 +1,76 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef THREAD_POOL_H
|
||||
#define THREAD_POOL_H
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenCL/opencl.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//
|
||||
// An atomic add operator
|
||||
cl_int ThreadPool_AtomicAdd( volatile cl_int *a, cl_int b ); // returns old value
|
||||
|
||||
// Your function prototype
|
||||
//
|
||||
// A function pointer to the function you want to execute in a multithreaded context. No
|
||||
// synchronization primitives are provided, other than the atomic add above. You may not
|
||||
// call ThreadPool_Do from your function. ThreadPool_AtomicAdd() and GetThreadCount() should
|
||||
// work, however.
|
||||
//
|
||||
// job ids and thread ids are 0 based. If number of jobs or threads was 8, they will numbered be 0 through 7.
|
||||
// Note that while every job will be run, it is not guaranteed that every thread will wake up before
|
||||
// the work is done.
|
||||
typedef cl_int (*TPFuncPtr)( cl_uint /*job_id*/, cl_uint /* thread_id */, void *userInfo );
|
||||
|
||||
// returns first non-zero result from func_ptr, or CL_SUCCESS if all are zero.
|
||||
// Some workitems may not run if a non-zero result is returned from func_ptr().
|
||||
// This function may not be called from a TPFuncPtr.
|
||||
cl_int ThreadPool_Do( TPFuncPtr func_ptr,
|
||||
cl_uint count,
|
||||
void *userInfo );
|
||||
|
||||
// Returns the number of worker threads that underlie the threadpool. The value passed
|
||||
// as the TPFuncPtrs thread_id will be between 0 and this value less one, inclusive.
|
||||
// This is safe to call from a TPFuncPtr.
|
||||
cl_uint GetThreadCount( void );
|
||||
|
||||
// SetThreadCount() may be used to artifically set the number of worker threads
|
||||
// If the value is 0 (the default) the number of threads will be determined based on
|
||||
// the number of CPU cores. If it is a unicore machine, then 2 will be used, so
|
||||
// that we still get some testing for thread safety.
|
||||
//
|
||||
// If count < 2 or the CL_TEST_SINGLE_THREADED environment variable is set then the
|
||||
// code will run single threaded, but will report an error to indicate that the test
|
||||
// is invalid. This option is intended for debugging purposes only. It is suggested
|
||||
// as a convention that test apps set the thread count to 1 in response to the -m flag.
|
||||
//
|
||||
// SetThreadCount() must be called before the first call to GetThreadCount() or ThreadPool_Do(),
|
||||
// otherwise the behavior is indefined. It may not be called from a TPFuncPtr.
|
||||
void SetThreadCount( int count );
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* THREAD_POOL_H */
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef THREAD_POOL_H
|
||||
#define THREAD_POOL_H
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenCL/opencl.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//
|
||||
// An atomic add operator
|
||||
cl_int ThreadPool_AtomicAdd( volatile cl_int *a, cl_int b ); // returns old value
|
||||
|
||||
// Your function prototype
|
||||
//
|
||||
// A function pointer to the function you want to execute in a multithreaded context. No
|
||||
// synchronization primitives are provided, other than the atomic add above. You may not
|
||||
// call ThreadPool_Do from your function. ThreadPool_AtomicAdd() and GetThreadCount() should
|
||||
// work, however.
|
||||
//
|
||||
// job ids and thread ids are 0 based. If number of jobs or threads was 8, they will numbered be 0 through 7.
|
||||
// Note that while every job will be run, it is not guaranteed that every thread will wake up before
|
||||
// the work is done.
|
||||
typedef cl_int (*TPFuncPtr)( cl_uint /*job_id*/, cl_uint /* thread_id */, void *userInfo );
|
||||
|
||||
// returns first non-zero result from func_ptr, or CL_SUCCESS if all are zero.
|
||||
// Some workitems may not run if a non-zero result is returned from func_ptr().
|
||||
// This function may not be called from a TPFuncPtr.
|
||||
cl_int ThreadPool_Do( TPFuncPtr func_ptr,
|
||||
cl_uint count,
|
||||
void *userInfo );
|
||||
|
||||
// Returns the number of worker threads that underlie the threadpool. The value passed
|
||||
// as the TPFuncPtrs thread_id will be between 0 and this value less one, inclusive.
|
||||
// This is safe to call from a TPFuncPtr.
|
||||
cl_uint GetThreadCount( void );
|
||||
|
||||
// SetThreadCount() may be used to artifically set the number of worker threads
|
||||
// If the value is 0 (the default) the number of threads will be determined based on
|
||||
// the number of CPU cores. If it is a unicore machine, then 2 will be used, so
|
||||
// that we still get some testing for thread safety.
|
||||
//
|
||||
// If count < 2 or the CL_TEST_SINGLE_THREADED environment variable is set then the
|
||||
// code will run single threaded, but will report an error to indicate that the test
|
||||
// is invalid. This option is intended for debugging purposes only. It is suggested
|
||||
// as a convention that test apps set the thread count to 1 in response to the -m flag.
|
||||
//
|
||||
// SetThreadCount() must be called before the first call to GetThreadCount() or ThreadPool_Do(),
|
||||
// otherwise the behavior is indefined. It may not be called from a TPFuncPtr.
|
||||
void SetThreadCount( int count );
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* THREAD_POOL_H */
|
||||
|
||||
@@ -1,253 +1,253 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef test_conformance_clImageHelper_h
|
||||
#define test_conformance_clImageHelper_h
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/opencl.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "errorHelpers.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// helper function to replace clCreateImage2D , to make the existing code use
|
||||
// the functions of version 1.2 and veriosn 1.1 respectively
|
||||
|
||||
inline cl_mem create_image_2d (cl_context context,
|
||||
cl_mem_flags flags,
|
||||
const cl_image_format *image_format,
|
||||
size_t image_width,
|
||||
size_t image_height,
|
||||
size_t image_row_pitch,
|
||||
void *host_ptr,
|
||||
cl_int *errcode_ret)
|
||||
{
|
||||
cl_mem mImage = NULL;
|
||||
|
||||
#ifdef CL_VERSION_1_2
|
||||
cl_image_desc image_desc_dest;
|
||||
image_desc_dest.image_type = CL_MEM_OBJECT_IMAGE2D;;
|
||||
image_desc_dest.image_width = image_width;
|
||||
image_desc_dest.image_height = image_height;
|
||||
image_desc_dest.image_depth= 0;// not usedfor 2d
|
||||
image_desc_dest.image_array_size = 0;// not used for 2d
|
||||
image_desc_dest.image_row_pitch = image_row_pitch;
|
||||
image_desc_dest.image_slice_pitch = 0;
|
||||
image_desc_dest.num_mip_levels = 0;
|
||||
image_desc_dest.num_samples = 0;
|
||||
image_desc_dest.buffer = NULL;// no image type of CL_MEM_OBJECT_IMAGE1D_BUFFER in CL_VERSION_1_1, so always is NULL
|
||||
mImage = clCreateImage( context, flags, image_format, &image_desc_dest, host_ptr, errcode_ret );
|
||||
if (errcode_ret && (*errcode_ret)) {
|
||||
// Log an info message and rely on the calling function to produce an error
|
||||
// if necessary.
|
||||
log_info("clCreateImage failed (%d)\n", *errcode_ret);
|
||||
}
|
||||
|
||||
#else
|
||||
mImage = clCreateImage2D( context, flags, image_format, image_width, image_height, image_row_pitch, host_ptr, errcode_ret );
|
||||
if (errcode_ret && (*errcode_ret)) {
|
||||
// Log an info message and rely on the calling function to produce an error
|
||||
// if necessary.
|
||||
log_info("clCreateImage2D failed (%d)\n", *errcode_ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
return mImage;
|
||||
}
|
||||
|
||||
inline cl_mem create_image_3d (cl_context context,
|
||||
cl_mem_flags flags,
|
||||
const cl_image_format *image_format,
|
||||
size_t image_width,
|
||||
size_t image_height,
|
||||
size_t image_depth,
|
||||
size_t image_row_pitch,
|
||||
size_t image_slice_pitch,
|
||||
void *host_ptr,
|
||||
cl_int *errcode_ret)
|
||||
{
|
||||
cl_mem mImage;
|
||||
|
||||
#ifdef CL_VERSION_1_2
|
||||
cl_image_desc image_desc;
|
||||
image_desc.image_type = CL_MEM_OBJECT_IMAGE3D;
|
||||
image_desc.image_width = image_width;
|
||||
image_desc.image_height = image_height;
|
||||
image_desc.image_depth = image_depth;
|
||||
image_desc.image_array_size = 0;// not used for one image
|
||||
image_desc.image_row_pitch = image_row_pitch;
|
||||
image_desc.image_slice_pitch = image_slice_pitch;
|
||||
image_desc.num_mip_levels = 0;
|
||||
image_desc.num_samples = 0;
|
||||
image_desc.buffer = NULL; // no image type of CL_MEM_OBJECT_IMAGE1D_BUFFER in CL_VERSION_1_1, so always is NULL
|
||||
mImage = clCreateImage( context,
|
||||
flags,
|
||||
image_format,
|
||||
&image_desc,
|
||||
host_ptr,
|
||||
errcode_ret );
|
||||
if (errcode_ret && (*errcode_ret)) {
|
||||
// Log an info message and rely on the calling function to produce an error
|
||||
// if necessary.
|
||||
log_info("clCreateImage failed (%d)\n", *errcode_ret);
|
||||
}
|
||||
|
||||
#else
|
||||
mImage = clCreateImage3D( context,
|
||||
flags, image_format,
|
||||
image_width,
|
||||
image_height,
|
||||
image_depth,
|
||||
image_row_pitch,
|
||||
image_slice_pitch,
|
||||
host_ptr,
|
||||
errcode_ret );
|
||||
if (errcode_ret && (*errcode_ret)) {
|
||||
// Log an info message and rely on the calling function to produce an error
|
||||
// if necessary.
|
||||
log_info("clCreateImage3D failed (%d)\n", *errcode_ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
return mImage;
|
||||
}
|
||||
|
||||
inline cl_mem create_image_2d_array (cl_context context,
|
||||
cl_mem_flags flags,
|
||||
const cl_image_format *image_format,
|
||||
size_t image_width,
|
||||
size_t image_height,
|
||||
size_t image_array_size,
|
||||
size_t image_row_pitch,
|
||||
size_t image_slice_pitch,
|
||||
void *host_ptr,
|
||||
cl_int *errcode_ret)
|
||||
{
|
||||
cl_mem mImage;
|
||||
|
||||
cl_image_desc image_desc;
|
||||
image_desc.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
|
||||
image_desc.image_width = image_width;
|
||||
image_desc.image_height = image_height;
|
||||
image_desc.image_depth = 1;
|
||||
image_desc.image_array_size = image_array_size;
|
||||
image_desc.image_row_pitch = image_row_pitch;
|
||||
image_desc.image_slice_pitch = image_slice_pitch;
|
||||
image_desc.num_mip_levels = 0;
|
||||
image_desc.num_samples = 0;
|
||||
image_desc.buffer = NULL;
|
||||
mImage = clCreateImage( context,
|
||||
flags,
|
||||
image_format,
|
||||
&image_desc,
|
||||
host_ptr,
|
||||
errcode_ret );
|
||||
if (errcode_ret && (*errcode_ret)) {
|
||||
// Log an info message and rely on the calling function to produce an error
|
||||
// if necessary.
|
||||
log_info("clCreateImage failed (%d)\n", *errcode_ret);
|
||||
}
|
||||
|
||||
return mImage;
|
||||
}
|
||||
|
||||
inline cl_mem create_image_1d_array (cl_context context,
|
||||
cl_mem_flags flags,
|
||||
const cl_image_format *image_format,
|
||||
size_t image_width,
|
||||
size_t image_array_size,
|
||||
size_t image_row_pitch,
|
||||
size_t image_slice_pitch,
|
||||
void *host_ptr,
|
||||
cl_int *errcode_ret)
|
||||
{
|
||||
cl_mem mImage;
|
||||
|
||||
cl_image_desc image_desc;
|
||||
image_desc.image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY;
|
||||
image_desc.image_width = image_width;
|
||||
image_desc.image_height = 1;
|
||||
image_desc.image_depth = 1;
|
||||
image_desc.image_array_size = image_array_size;
|
||||
image_desc.image_row_pitch = image_row_pitch;
|
||||
image_desc.image_slice_pitch = image_slice_pitch;
|
||||
image_desc.num_mip_levels = 0;
|
||||
image_desc.num_samples = 0;
|
||||
image_desc.buffer = NULL;
|
||||
mImage = clCreateImage( context,
|
||||
flags,
|
||||
image_format,
|
||||
&image_desc,
|
||||
host_ptr,
|
||||
errcode_ret );
|
||||
if (errcode_ret && (*errcode_ret)) {
|
||||
// Log an info message and rely on the calling function to produce an error
|
||||
// if necessary.
|
||||
log_info("clCreateImage failed (%d)\n", *errcode_ret);
|
||||
}
|
||||
|
||||
return mImage;
|
||||
}
|
||||
|
||||
inline cl_mem create_image_1d (cl_context context,
|
||||
cl_mem_flags flags,
|
||||
const cl_image_format *image_format,
|
||||
size_t image_width,
|
||||
size_t image_row_pitch,
|
||||
void *host_ptr,
|
||||
cl_mem buffer,
|
||||
cl_int *errcode_ret)
|
||||
{
|
||||
cl_mem mImage;
|
||||
|
||||
cl_image_desc image_desc;
|
||||
image_desc.image_type = buffer ? CL_MEM_OBJECT_IMAGE1D_BUFFER: CL_MEM_OBJECT_IMAGE1D;
|
||||
image_desc.image_width = image_width;
|
||||
image_desc.image_height = 1;
|
||||
image_desc.image_depth = 1;
|
||||
image_desc.image_row_pitch = image_row_pitch;
|
||||
image_desc.image_slice_pitch = 0;
|
||||
image_desc.num_mip_levels = 0;
|
||||
image_desc.num_samples = 0;
|
||||
image_desc.buffer = buffer;
|
||||
mImage = clCreateImage( context,
|
||||
flags,
|
||||
image_format,
|
||||
&image_desc,
|
||||
host_ptr,
|
||||
errcode_ret );
|
||||
if (errcode_ret && (*errcode_ret)) {
|
||||
// Log an info message and rely on the calling function to produce an error
|
||||
// if necessary.
|
||||
log_info("clCreateImage failed (%d)\n", *errcode_ret);
|
||||
}
|
||||
|
||||
return mImage;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef test_conformance_clImageHelper_h
|
||||
#define test_conformance_clImageHelper_h
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/opencl.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "errorHelpers.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// helper function to replace clCreateImage2D , to make the existing code use
|
||||
// the functions of version 1.2 and veriosn 1.1 respectively
|
||||
|
||||
inline cl_mem create_image_2d (cl_context context,
|
||||
cl_mem_flags flags,
|
||||
const cl_image_format *image_format,
|
||||
size_t image_width,
|
||||
size_t image_height,
|
||||
size_t image_row_pitch,
|
||||
void *host_ptr,
|
||||
cl_int *errcode_ret)
|
||||
{
|
||||
cl_mem mImage = NULL;
|
||||
|
||||
#ifdef CL_VERSION_1_2
|
||||
cl_image_desc image_desc_dest;
|
||||
image_desc_dest.image_type = CL_MEM_OBJECT_IMAGE2D;;
|
||||
image_desc_dest.image_width = image_width;
|
||||
image_desc_dest.image_height = image_height;
|
||||
image_desc_dest.image_depth= 0;// not usedfor 2d
|
||||
image_desc_dest.image_array_size = 0;// not used for 2d
|
||||
image_desc_dest.image_row_pitch = image_row_pitch;
|
||||
image_desc_dest.image_slice_pitch = 0;
|
||||
image_desc_dest.num_mip_levels = 0;
|
||||
image_desc_dest.num_samples = 0;
|
||||
image_desc_dest.buffer = NULL;// no image type of CL_MEM_OBJECT_IMAGE1D_BUFFER in CL_VERSION_1_1, so always is NULL
|
||||
mImage = clCreateImage( context, flags, image_format, &image_desc_dest, host_ptr, errcode_ret );
|
||||
if (errcode_ret && (*errcode_ret)) {
|
||||
// Log an info message and rely on the calling function to produce an error
|
||||
// if necessary.
|
||||
log_info("clCreateImage failed (%d)\n", *errcode_ret);
|
||||
}
|
||||
|
||||
#else
|
||||
mImage = clCreateImage2D( context, flags, image_format, image_width, image_height, image_row_pitch, host_ptr, errcode_ret );
|
||||
if (errcode_ret && (*errcode_ret)) {
|
||||
// Log an info message and rely on the calling function to produce an error
|
||||
// if necessary.
|
||||
log_info("clCreateImage2D failed (%d)\n", *errcode_ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
return mImage;
|
||||
}
|
||||
|
||||
inline cl_mem create_image_3d (cl_context context,
|
||||
cl_mem_flags flags,
|
||||
const cl_image_format *image_format,
|
||||
size_t image_width,
|
||||
size_t image_height,
|
||||
size_t image_depth,
|
||||
size_t image_row_pitch,
|
||||
size_t image_slice_pitch,
|
||||
void *host_ptr,
|
||||
cl_int *errcode_ret)
|
||||
{
|
||||
cl_mem mImage;
|
||||
|
||||
#ifdef CL_VERSION_1_2
|
||||
cl_image_desc image_desc;
|
||||
image_desc.image_type = CL_MEM_OBJECT_IMAGE3D;
|
||||
image_desc.image_width = image_width;
|
||||
image_desc.image_height = image_height;
|
||||
image_desc.image_depth = image_depth;
|
||||
image_desc.image_array_size = 0;// not used for one image
|
||||
image_desc.image_row_pitch = image_row_pitch;
|
||||
image_desc.image_slice_pitch = image_slice_pitch;
|
||||
image_desc.num_mip_levels = 0;
|
||||
image_desc.num_samples = 0;
|
||||
image_desc.buffer = NULL; // no image type of CL_MEM_OBJECT_IMAGE1D_BUFFER in CL_VERSION_1_1, so always is NULL
|
||||
mImage = clCreateImage( context,
|
||||
flags,
|
||||
image_format,
|
||||
&image_desc,
|
||||
host_ptr,
|
||||
errcode_ret );
|
||||
if (errcode_ret && (*errcode_ret)) {
|
||||
// Log an info message and rely on the calling function to produce an error
|
||||
// if necessary.
|
||||
log_info("clCreateImage failed (%d)\n", *errcode_ret);
|
||||
}
|
||||
|
||||
#else
|
||||
mImage = clCreateImage3D( context,
|
||||
flags, image_format,
|
||||
image_width,
|
||||
image_height,
|
||||
image_depth,
|
||||
image_row_pitch,
|
||||
image_slice_pitch,
|
||||
host_ptr,
|
||||
errcode_ret );
|
||||
if (errcode_ret && (*errcode_ret)) {
|
||||
// Log an info message and rely on the calling function to produce an error
|
||||
// if necessary.
|
||||
log_info("clCreateImage3D failed (%d)\n", *errcode_ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
return mImage;
|
||||
}
|
||||
|
||||
inline cl_mem create_image_2d_array (cl_context context,
|
||||
cl_mem_flags flags,
|
||||
const cl_image_format *image_format,
|
||||
size_t image_width,
|
||||
size_t image_height,
|
||||
size_t image_array_size,
|
||||
size_t image_row_pitch,
|
||||
size_t image_slice_pitch,
|
||||
void *host_ptr,
|
||||
cl_int *errcode_ret)
|
||||
{
|
||||
cl_mem mImage;
|
||||
|
||||
cl_image_desc image_desc;
|
||||
image_desc.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
|
||||
image_desc.image_width = image_width;
|
||||
image_desc.image_height = image_height;
|
||||
image_desc.image_depth = 1;
|
||||
image_desc.image_array_size = image_array_size;
|
||||
image_desc.image_row_pitch = image_row_pitch;
|
||||
image_desc.image_slice_pitch = image_slice_pitch;
|
||||
image_desc.num_mip_levels = 0;
|
||||
image_desc.num_samples = 0;
|
||||
image_desc.buffer = NULL;
|
||||
mImage = clCreateImage( context,
|
||||
flags,
|
||||
image_format,
|
||||
&image_desc,
|
||||
host_ptr,
|
||||
errcode_ret );
|
||||
if (errcode_ret && (*errcode_ret)) {
|
||||
// Log an info message and rely on the calling function to produce an error
|
||||
// if necessary.
|
||||
log_info("clCreateImage failed (%d)\n", *errcode_ret);
|
||||
}
|
||||
|
||||
return mImage;
|
||||
}
|
||||
|
||||
inline cl_mem create_image_1d_array (cl_context context,
|
||||
cl_mem_flags flags,
|
||||
const cl_image_format *image_format,
|
||||
size_t image_width,
|
||||
size_t image_array_size,
|
||||
size_t image_row_pitch,
|
||||
size_t image_slice_pitch,
|
||||
void *host_ptr,
|
||||
cl_int *errcode_ret)
|
||||
{
|
||||
cl_mem mImage;
|
||||
|
||||
cl_image_desc image_desc;
|
||||
image_desc.image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY;
|
||||
image_desc.image_width = image_width;
|
||||
image_desc.image_height = 1;
|
||||
image_desc.image_depth = 1;
|
||||
image_desc.image_array_size = image_array_size;
|
||||
image_desc.image_row_pitch = image_row_pitch;
|
||||
image_desc.image_slice_pitch = image_slice_pitch;
|
||||
image_desc.num_mip_levels = 0;
|
||||
image_desc.num_samples = 0;
|
||||
image_desc.buffer = NULL;
|
||||
mImage = clCreateImage( context,
|
||||
flags,
|
||||
image_format,
|
||||
&image_desc,
|
||||
host_ptr,
|
||||
errcode_ret );
|
||||
if (errcode_ret && (*errcode_ret)) {
|
||||
// Log an info message and rely on the calling function to produce an error
|
||||
// if necessary.
|
||||
log_info("clCreateImage failed (%d)\n", *errcode_ret);
|
||||
}
|
||||
|
||||
return mImage;
|
||||
}
|
||||
|
||||
inline cl_mem create_image_1d (cl_context context,
|
||||
cl_mem_flags flags,
|
||||
const cl_image_format *image_format,
|
||||
size_t image_width,
|
||||
size_t image_row_pitch,
|
||||
void *host_ptr,
|
||||
cl_mem buffer,
|
||||
cl_int *errcode_ret)
|
||||
{
|
||||
cl_mem mImage;
|
||||
|
||||
cl_image_desc image_desc;
|
||||
image_desc.image_type = buffer ? CL_MEM_OBJECT_IMAGE1D_BUFFER: CL_MEM_OBJECT_IMAGE1D;
|
||||
image_desc.image_width = image_width;
|
||||
image_desc.image_height = 1;
|
||||
image_desc.image_depth = 1;
|
||||
image_desc.image_row_pitch = image_row_pitch;
|
||||
image_desc.image_slice_pitch = 0;
|
||||
image_desc.num_mip_levels = 0;
|
||||
image_desc.num_samples = 0;
|
||||
image_desc.buffer = buffer;
|
||||
mImage = clCreateImage( context,
|
||||
flags,
|
||||
image_format,
|
||||
&image_desc,
|
||||
host_ptr,
|
||||
errcode_ret );
|
||||
if (errcode_ret && (*errcode_ret)) {
|
||||
// Log an info message and rely on the calling function to produce an error
|
||||
// if necessary.
|
||||
log_info("clCreateImage failed (%d)\n", *errcode_ret);
|
||||
}
|
||||
|
||||
return mImage;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,200 +1,393 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _COMPAT_H_
|
||||
#define _COMPAT_H_
|
||||
|
||||
#if defined(_WIN32) && defined (_MSC_VER)
|
||||
|
||||
#include <Windows.h>
|
||||
#include <Winbase.h>
|
||||
#include <CL/cl.h>
|
||||
#include <float.h>
|
||||
#include <xmmintrin.h>
|
||||
|
||||
#define MAKE_HEX_FLOAT(x,y,z) ((float)ldexp( (float)(y), z))
|
||||
#define MAKE_HEX_DOUBLE(x,y,z) ldexp( (double)(y), z)
|
||||
#define MAKE_HEX_LONG(x,y,z) ((long double) ldexp( (long double)(y), z))
|
||||
|
||||
#define isfinite(x) _finite(x)
|
||||
|
||||
#if !defined(__cplusplus)
|
||||
typedef char bool;
|
||||
#define inline
|
||||
|
||||
#else
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef char int8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef short int16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef int int32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef long long int64_t;
|
||||
|
||||
#define MAXPATHLEN MAX_PATH
|
||||
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
|
||||
|
||||
#define INFINITY (FLT_MAX + FLT_MAX)
|
||||
//#define NAN (INFINITY | 1)
|
||||
//const static int PINFBITPATT_SP32 = INFINITY;
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338327950288
|
||||
#endif
|
||||
|
||||
|
||||
#define isnan( x ) ((x) != (x))
|
||||
#define isinf( _x) ((_x) == INFINITY || (_x) == -INFINITY)
|
||||
|
||||
double rint( double x);
|
||||
float rintf( float x);
|
||||
long double rintl( long double x);
|
||||
|
||||
float cbrtf( float );
|
||||
double cbrt( double );
|
||||
|
||||
int ilogb( double x);
|
||||
int ilogbf (float x);
|
||||
int ilogbl(long double x);
|
||||
|
||||
double fmax(double x, double y);
|
||||
double fmin(double x, double y);
|
||||
float fmaxf( float x, float y );
|
||||
float fminf(float x, float y);
|
||||
|
||||
double log2(double x);
|
||||
long double log2l(long double x);
|
||||
|
||||
double exp2(double x);
|
||||
long double exp2l(long double x);
|
||||
|
||||
double fdim(double x, double y);
|
||||
float fdimf(float x, float y);
|
||||
long double fdiml(long double x, long double y);
|
||||
|
||||
double remquo( double x, double y, int *quo);
|
||||
float remquof( float x, float y, int *quo);
|
||||
long double remquol( long double x, long double y, int *quo);
|
||||
|
||||
long double scalblnl(long double x, long n);
|
||||
|
||||
inline long long
|
||||
llabs(long long __x) { return __x >= 0 ? __x : -__x; }
|
||||
|
||||
|
||||
// end of math functions
|
||||
|
||||
uint64_t ReadTime( void );
|
||||
double SubtractTime( uint64_t endTime, uint64_t startTime );
|
||||
|
||||
#define sleep(X) Sleep(1000*X)
|
||||
#define snprintf sprintf_s
|
||||
//#define hypotl _hypot
|
||||
|
||||
float make_nan();
|
||||
float nanf( const char* str);
|
||||
double nan( const char* str);
|
||||
long double nanl( const char* str);
|
||||
|
||||
//#if defined USE_BOOST
|
||||
//#include <boost/math/tr1.hpp>
|
||||
//double hypot(double x, double y);
|
||||
float hypotf(float x, float y);
|
||||
long double hypotl(long double x, long double y) ;
|
||||
double lgamma(double x);
|
||||
float lgammaf(float x);
|
||||
|
||||
double trunc(double x);
|
||||
float truncf(float x);
|
||||
|
||||
double log1p(double x);
|
||||
float log1pf(float x);
|
||||
long double log1pl(long double x);
|
||||
|
||||
double copysign(double x, double y);
|
||||
float copysignf(float x, float y);
|
||||
long double copysignl(long double x, long double y);
|
||||
|
||||
long lround(double x);
|
||||
long lroundf(float x);
|
||||
//long lroundl(long double x)
|
||||
|
||||
double round(double x);
|
||||
float roundf(float x);
|
||||
long double roundl(long double x);
|
||||
|
||||
int signbit(double x);
|
||||
int signbitf(float x);
|
||||
|
||||
//bool signbitl(long double x) { return boost::math::tr1::signbit<long double>(x); }
|
||||
//#endif // USE_BOOST
|
||||
|
||||
long int lrint (double flt);
|
||||
long int lrintf (float flt);
|
||||
|
||||
|
||||
float int2float (int32_t ix);
|
||||
int32_t float2int (float fx);
|
||||
|
||||
/** Returns the number of leading 0-bits in x,
|
||||
starting at the most significant bit position.
|
||||
If x is 0, the result is undefined.
|
||||
*/
|
||||
int __builtin_clz(unsigned int pattern);
|
||||
|
||||
|
||||
static const double zero= 0.00000000000000000000e+00;
|
||||
#define NAN (INFINITY - INFINITY)
|
||||
#define HUGE_VALF (float)HUGE_VAL
|
||||
|
||||
int usleep(int usec);
|
||||
|
||||
// reimplement fenv.h because windows doesn't have it
|
||||
#define FE_INEXACT 0x0020
|
||||
#define FE_UNDERFLOW 0x0010
|
||||
#define FE_OVERFLOW 0x0008
|
||||
#define FE_DIVBYZERO 0x0004
|
||||
#define FE_INVALID 0x0001
|
||||
#define FE_ALL_EXCEPT 0x003D
|
||||
|
||||
int fetestexcept(int excepts);
|
||||
int feclearexcept(int excepts);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else // !((defined(_WIN32) && defined(_MSC_VER)
|
||||
#if defined(__MINGW32__)
|
||||
#include <windows.h>
|
||||
#define sleep(X) Sleep(1000*X)
|
||||
|
||||
#endif
|
||||
#define MAKE_HEX_FLOAT(x,y,z) x
|
||||
#define MAKE_HEX_DOUBLE(x,y,z) x
|
||||
#define MAKE_HEX_LONG(x,y,z) x
|
||||
|
||||
#endif // !((defined(_WIN32) && defined(_MSC_VER)
|
||||
|
||||
|
||||
#endif // _COMPAT_H_
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _COMPAT_H_
|
||||
#define _COMPAT_H_
|
||||
|
||||
#if defined(_WIN32) && defined (_MSC_VER)
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN_C extern "C"
|
||||
#else
|
||||
#define EXTERN_C
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// stdlib.h
|
||||
//
|
||||
|
||||
#include <stdlib.h> // On Windows, _MAX_PATH defined there.
|
||||
|
||||
// llabs appeared in MS C v16 (VS 10/2010).
|
||||
#if defined( _MSC_VER ) && _MSC_VER <= 1500
|
||||
EXTERN_C inline long long llabs(long long __x) { return __x >= 0 ? __x : -__x; }
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// stdbool.h
|
||||
//
|
||||
|
||||
// stdbool.h appeared in MS C v18 (VS 12/2013).
|
||||
#if defined( _MSC_VER ) && MSC_VER <= 1700
|
||||
#if !defined(__cplusplus)
|
||||
typedef char bool;
|
||||
#define true 1
|
||||
#define false 0
|
||||
#endif
|
||||
#else
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//
|
||||
// stdint.h
|
||||
//
|
||||
|
||||
// stdint.h appeared in MS C v16 (VS 10/2010) and Intel C v12.
|
||||
#if defined( _MSC_VER ) && ( ! defined( __INTEL_COMPILER ) && _MSC_VER <= 1500 || defined( __INTEL_COMPILER ) && __INTEL_COMPILER < 1200 )
|
||||
typedef unsigned char uint8_t;
|
||||
typedef char int8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef short int16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef int int32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef long long int64_t;
|
||||
#else
|
||||
#ifndef __STDC_LIMIT_MACROS
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//
|
||||
// float.h
|
||||
//
|
||||
|
||||
#include <float.h>
|
||||
|
||||
|
||||
|
||||
//
|
||||
// fenv.h
|
||||
//
|
||||
|
||||
// fenv.h appeared in MS C v18 (VS 12/2013).
|
||||
#if defined( _MSC_VER ) && _MSC_VER <= 1700 && ! defined( __INTEL_COMPILER )
|
||||
// reimplement fenv.h because windows doesn't have it
|
||||
#define FE_INEXACT 0x0020
|
||||
#define FE_UNDERFLOW 0x0010
|
||||
#define FE_OVERFLOW 0x0008
|
||||
#define FE_DIVBYZERO 0x0004
|
||||
#define FE_INVALID 0x0001
|
||||
#define FE_ALL_EXCEPT 0x003D
|
||||
int fetestexcept(int excepts);
|
||||
int feclearexcept(int excepts);
|
||||
#else
|
||||
#include <fenv.h>
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// math.h
|
||||
//
|
||||
|
||||
#if defined( __INTEL_COMPILER )
|
||||
#include <mathimf.h>
|
||||
#else
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
#if defined( _MSC_VER )
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338327950288
|
||||
#endif
|
||||
|
||||
#if ! defined( __INTEL_COMPILER )
|
||||
|
||||
#ifndef NAN
|
||||
#define NAN (INFINITY - INFINITY)
|
||||
#endif
|
||||
#ifndef HUGE_VALF
|
||||
#define HUGE_VALF (float)HUGE_VAL
|
||||
#endif
|
||||
#ifndef INFINITY
|
||||
#define INFINITY (FLT_MAX + FLT_MAX)
|
||||
#endif
|
||||
#ifndef isfinite
|
||||
#define isfinite(x) _finite(x)
|
||||
#endif
|
||||
#ifndef isnan
|
||||
#define isnan( x ) ((x) != (x))
|
||||
#endif
|
||||
#ifndef isinf
|
||||
#define isinf( _x) ((_x) == INFINITY || (_x) == -INFINITY)
|
||||
#endif
|
||||
|
||||
double rint( double x);
|
||||
float rintf( float x);
|
||||
long double rintl( long double x);
|
||||
|
||||
float cbrtf( float );
|
||||
double cbrt( double );
|
||||
|
||||
int ilogb( double x);
|
||||
int ilogbf (float x);
|
||||
int ilogbl(long double x);
|
||||
|
||||
double fmax(double x, double y);
|
||||
double fmin(double x, double y);
|
||||
float fmaxf( float x, float y );
|
||||
float fminf(float x, float y);
|
||||
|
||||
double log2(double x);
|
||||
long double log2l(long double x);
|
||||
|
||||
double exp2(double x);
|
||||
long double exp2l(long double x);
|
||||
|
||||
double fdim(double x, double y);
|
||||
float fdimf(float x, float y);
|
||||
long double fdiml(long double x, long double y);
|
||||
|
||||
double remquo( double x, double y, int *quo);
|
||||
float remquof( float x, float y, int *quo);
|
||||
long double remquol( long double x, long double y, int *quo);
|
||||
|
||||
long double scalblnl(long double x, long n);
|
||||
|
||||
float hypotf(float x, float y);
|
||||
long double hypotl(long double x, long double y) ;
|
||||
double lgamma(double x);
|
||||
float lgammaf(float x);
|
||||
|
||||
double trunc(double x);
|
||||
float truncf(float x);
|
||||
|
||||
double log1p(double x);
|
||||
float log1pf(float x);
|
||||
long double log1pl(long double x);
|
||||
|
||||
double copysign(double x, double y);
|
||||
float copysignf(float x, float y);
|
||||
long double copysignl(long double x, long double y);
|
||||
|
||||
long lround(double x);
|
||||
long lroundf(float x);
|
||||
//long lroundl(long double x)
|
||||
|
||||
double round(double x);
|
||||
float roundf(float x);
|
||||
long double roundl(long double x);
|
||||
|
||||
int cf_signbit(double x);
|
||||
int cf_signbitf(float x);
|
||||
|
||||
// Added in _MSC_VER == 1800 (Visual Studio 2013)
|
||||
#if _MSC_VER < 1800
|
||||
static int signbit(double x) { return cf_signbit(x); }
|
||||
#endif
|
||||
static int signbitf(float x) { return cf_signbitf(x); }
|
||||
|
||||
long int lrint (double flt);
|
||||
long int lrintf (float flt);
|
||||
|
||||
float int2float (int32_t ix);
|
||||
int32_t float2int (float fx);
|
||||
|
||||
#endif
|
||||
|
||||
#if ! defined( __INTEL_COMPILER ) || __INTEL_COMPILER < 1300
|
||||
// These functions appeared in Intel C v13.
|
||||
float nanf( const char* str);
|
||||
double nan( const char* str);
|
||||
long double nanl( const char* str);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( __ANDROID__ )
|
||||
#define log2(X) (log(X)/log(2))
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//
|
||||
// stdio.h
|
||||
//
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// snprintf added in _MSC_VER == 1900 (Visual Studio 2015)
|
||||
#if _MSC_VER < 1900
|
||||
#define snprintf sprintf_s
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//
|
||||
// unistd.h
|
||||
//
|
||||
|
||||
#if defined( _MSC_VER )
|
||||
EXTERN_C unsigned int sleep( unsigned int sec );
|
||||
EXTERN_C int usleep( int usec );
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//
|
||||
// syscall.h
|
||||
//
|
||||
|
||||
#if defined( __ANDROID__ )
|
||||
// Android bionic's isn't providing SYS_sysctl wrappers.
|
||||
#define SYS__sysctl __NR__sysctl
|
||||
#elif defined( __aarch64__ )
|
||||
// Enable deprecated syscalls on arm 64-bit.
|
||||
#define __ARCH_WANT_SYSCALL_DEPRECATED
|
||||
// And use the NR variant of syscall too.
|
||||
#define SYS__sysctl __NR__sysctl
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Some tests use _malloca which defined in malloc.h.
|
||||
#if !defined (__APPLE__)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// ???
|
||||
//
|
||||
|
||||
#if defined( _MSC_VER )
|
||||
|
||||
#define MAXPATHLEN _MAX_PATH
|
||||
|
||||
EXTERN_C uint64_t ReadTime( void );
|
||||
EXTERN_C double SubtractTime( uint64_t endTime, uint64_t startTime );
|
||||
|
||||
/** Returns the number of leading 0-bits in x,
|
||||
starting at the most significant bit position.
|
||||
If x is 0, the result is undefined.
|
||||
*/
|
||||
EXTERN_C int __builtin_clz(unsigned int pattern);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x,y) (((x)<(y))?(x):(y))
|
||||
#endif
|
||||
#ifndef MAX
|
||||
#define MAX(x,y) (((x)>(y))?(x):(y))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------------------------
|
||||
WARNING: DO NOT USE THESE MACROS: MAKE_HEX_FLOAT, MAKE_HEX_DOUBLE, MAKE_HEX_LONG.
|
||||
|
||||
This is a typical usage of the macros:
|
||||
|
||||
double yhi = MAKE_HEX_DOUBLE(0x1.5555555555555p-2,0x15555555555555LL,-2);
|
||||
|
||||
(taken from math_brute_force/reference_math.c). There are two problems:
|
||||
|
||||
1. There is an error here. On Windows in will produce incorrect result
|
||||
`0x1.5555555555555p+50'. To have a correct result it should be written as
|
||||
`MAKE_HEX_DOUBLE(0x1.5555555555555p-2,0x15555555555555LL,-54)'. A proper value of the
|
||||
third argument is not obvious -- sometimes it should be the same as exponent of the
|
||||
first argument, but sometimes not.
|
||||
|
||||
2. Information is duplicated. It is easy to make a mistake.
|
||||
|
||||
Use HEX_FLT, HEX_DBL, HEX_LDBL macros instead (see them in the bottom of the file).
|
||||
------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
#if defined ( _MSC_VER ) && ! defined( __INTEL_COMPILER )
|
||||
|
||||
#define MAKE_HEX_FLOAT(x,y,z) ((float)ldexp( (float)(y), z))
|
||||
#define MAKE_HEX_DOUBLE(x,y,z) ldexp( (double)(y), z)
|
||||
#define MAKE_HEX_LONG(x,y,z) ((long double) ldexp( (long double)(y), z))
|
||||
|
||||
#else
|
||||
|
||||
// Do not use these macros in new code, use HEX_FLT, HEX_DBL, HEX_LDBL instead.
|
||||
#define MAKE_HEX_FLOAT(x,y,z) x
|
||||
#define MAKE_HEX_DOUBLE(x,y,z) x
|
||||
#define MAKE_HEX_LONG(x,y,z) x
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------------------------
|
||||
HEX_FLT, HEXT_DBL, HEX_LDBL -- Create hex floating point literal of type float, double, long
|
||||
double respectively. Arguments:
|
||||
|
||||
sm -- sign of number,
|
||||
int -- integer part of mantissa (without `0x' prefix),
|
||||
fract -- fractional part of mantissa (without decimal point and `L' or `LL' suffixes),
|
||||
se -- sign of exponent,
|
||||
exp -- absolute value of (binary) exponent.
|
||||
|
||||
Example:
|
||||
|
||||
double yhi = HEX_DBL( +, 1, 5555555555555, -, 2 ); // == 0x1.5555555555555p-2
|
||||
|
||||
Note:
|
||||
|
||||
We have to pass signs as separate arguments because gcc pass negative integer values
|
||||
(e. g. `-2') into a macro as two separate tokens, so `HEX_FLT( 1, 0, -2 )' produces result
|
||||
`0x1.0p- 2' (note a space between minus and two) which is not a correct floating point
|
||||
literal.
|
||||
------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
#if defined ( _MSC_VER ) && ! defined( __INTEL_COMPILER )
|
||||
// If compiler does not support hex floating point literals:
|
||||
#define HEX_FLT( sm, int, fract, se, exp ) sm ldexpf( (float)( 0x ## int ## fract ## UL ), se exp + ilogbf( (float) 0x ## int ) - ilogbf( ( float )( 0x ## int ## fract ## UL ) ) )
|
||||
#define HEX_DBL( sm, int, fract, se, exp ) sm ldexp( (double)( 0x ## int ## fract ## ULL ), se exp + ilogb( (double) 0x ## int ) - ilogb( ( double )( 0x ## int ## fract ## ULL ) ) )
|
||||
#define HEX_LDBL( sm, int, fract, se, exp ) sm ldexpl( (long double)( 0x ## int ## fract ## ULL ), se exp + ilogbl( (long double) 0x ## int ) - ilogbl( ( long double )( 0x ## int ## fract ## ULL ) ) )
|
||||
#else
|
||||
// If compiler supports hex floating point literals: just concatenate all the parts into a literal.
|
||||
#define HEX_FLT( sm, int, fract, se, exp ) sm 0x ## int ## . ## fract ## p ## se ## exp ## F
|
||||
#define HEX_DBL( sm, int, fract, se, exp ) sm 0x ## int ## . ## fract ## p ## se ## exp
|
||||
#define HEX_LDBL( sm, int, fract, se, exp ) sm 0x ## int ## . ## fract ## p ## se ## exp ## L
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
#include <Windows.h>
|
||||
#define sleep(sec) Sleep((sec) * 1000)
|
||||
#endif
|
||||
|
||||
#endif // _COMPAT_H_
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,127 +1,126 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _conversions_h
|
||||
#define _conversions_h
|
||||
|
||||
#include "errorHelpers.h"
|
||||
#include "mt19937.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include "compat.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Note: the next three all have to match in size and order!! */
|
||||
|
||||
enum ExplicitTypes
|
||||
{
|
||||
kBool = 0,
|
||||
kChar,
|
||||
kUChar,
|
||||
kUnsignedChar,
|
||||
kShort,
|
||||
kUShort,
|
||||
kUnsignedShort,
|
||||
kInt,
|
||||
kUInt,
|
||||
kUnsignedInt,
|
||||
kLong,
|
||||
kULong,
|
||||
kUnsignedLong,
|
||||
kFloat,
|
||||
kHalf,
|
||||
kDouble,
|
||||
kNumExplicitTypes
|
||||
};
|
||||
|
||||
typedef enum ExplicitTypes ExplicitType;
|
||||
|
||||
enum RoundingTypes
|
||||
{
|
||||
kRoundToEven = 0,
|
||||
kRoundToZero,
|
||||
kRoundToPosInf,
|
||||
kRoundToNegInf,
|
||||
kRoundToNearest,
|
||||
|
||||
kNumRoundingTypes,
|
||||
|
||||
kDefaultRoundingType = kRoundToNearest
|
||||
};
|
||||
|
||||
typedef enum RoundingTypes RoundingType;
|
||||
|
||||
extern void print_type_to_string(ExplicitType type, void *data, char* string);
|
||||
extern size_t get_explicit_type_size( ExplicitType type );
|
||||
extern const char * get_explicit_type_name( ExplicitType type );
|
||||
extern void convert_explicit_value( void *inRaw, void *outRaw, ExplicitType inType, bool saturate, RoundingType roundType, ExplicitType outType );
|
||||
|
||||
extern void generate_random_data( ExplicitType type, size_t count, MTdata d, void *outData );
|
||||
extern void * create_random_data( ExplicitType type, MTdata d, size_t count );
|
||||
|
||||
extern cl_long read_upscale_signed( void *inRaw, ExplicitType inType );
|
||||
extern cl_ulong read_upscale_unsigned( void *inRaw, ExplicitType inType );
|
||||
extern float read_as_float( void *inRaw, ExplicitType inType );
|
||||
|
||||
extern float get_random_float(float low, float high, MTdata d);
|
||||
extern double get_random_double(double low, double high, MTdata d);
|
||||
extern float any_float( MTdata d );
|
||||
extern double any_double( MTdata d );
|
||||
|
||||
extern int random_in_range( int minV, int maxV, MTdata d );
|
||||
|
||||
size_t get_random_size_t(size_t low, size_t high, MTdata d);
|
||||
|
||||
// Note: though this takes a double, this is for use with single precision tests
|
||||
static inline int IsFloatSubnormal( float x )
|
||||
{
|
||||
#if 2 == FLT_RADIX
|
||||
// Do this in integer to avoid problems with FTZ behavior
|
||||
union{ float d; uint32_t u;}u;
|
||||
u.d = fabsf(x);
|
||||
return (u.u-1) < 0x007fffffU;
|
||||
#else
|
||||
// rely on floating point hardware for non-radix2 non-IEEE-754 hardware -- will fail if you flush subnormals to zero
|
||||
return fabs(x) < (double) FLT_MIN && x != 0.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int IsDoubleSubnormal( double x )
|
||||
{
|
||||
#if 2 == FLT_RADIX
|
||||
// Do this in integer to avoid problems with FTZ behavior
|
||||
union{ double d; uint64_t u;}u;
|
||||
u.d = fabs( x);
|
||||
return (u.u-1) < 0x000fffffffffffffULL;
|
||||
#else
|
||||
// rely on floating point hardware for non-radix2 non-IEEE-754 hardware -- will fail if you flush subnormals to zero
|
||||
return fabs(x) < (double) DBL_MIN && x != 0.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _conversions_h
|
||||
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _conversions_h
|
||||
#define _conversions_h
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#include "errorHelpers.h"
|
||||
#include "mt19937.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Note: the next three all have to match in size and order!! */
|
||||
|
||||
enum ExplicitTypes
|
||||
{
|
||||
kBool = 0,
|
||||
kChar,
|
||||
kUChar,
|
||||
kUnsignedChar,
|
||||
kShort,
|
||||
kUShort,
|
||||
kUnsignedShort,
|
||||
kInt,
|
||||
kUInt,
|
||||
kUnsignedInt,
|
||||
kLong,
|
||||
kULong,
|
||||
kUnsignedLong,
|
||||
kFloat,
|
||||
kHalf,
|
||||
kDouble,
|
||||
kNumExplicitTypes
|
||||
};
|
||||
|
||||
typedef enum ExplicitTypes ExplicitType;
|
||||
|
||||
enum RoundingTypes
|
||||
{
|
||||
kRoundToEven = 0,
|
||||
kRoundToZero,
|
||||
kRoundToPosInf,
|
||||
kRoundToNegInf,
|
||||
kRoundToNearest,
|
||||
|
||||
kNumRoundingTypes,
|
||||
|
||||
kDefaultRoundingType = kRoundToNearest
|
||||
};
|
||||
|
||||
typedef enum RoundingTypes RoundingType;
|
||||
|
||||
extern void print_type_to_string(ExplicitType type, void *data, char* string);
|
||||
extern size_t get_explicit_type_size( ExplicitType type );
|
||||
extern const char * get_explicit_type_name( ExplicitType type );
|
||||
extern void convert_explicit_value( void *inRaw, void *outRaw, ExplicitType inType, bool saturate, RoundingType roundType, ExplicitType outType );
|
||||
|
||||
extern void generate_random_data( ExplicitType type, size_t count, MTdata d, void *outData );
|
||||
extern void * create_random_data( ExplicitType type, MTdata d, size_t count );
|
||||
|
||||
extern cl_long read_upscale_signed( void *inRaw, ExplicitType inType );
|
||||
extern cl_ulong read_upscale_unsigned( void *inRaw, ExplicitType inType );
|
||||
extern float read_as_float( void *inRaw, ExplicitType inType );
|
||||
|
||||
extern float get_random_float(float low, float high, MTdata d);
|
||||
extern double get_random_double(double low, double high, MTdata d);
|
||||
extern float any_float( MTdata d );
|
||||
extern double any_double( MTdata d );
|
||||
|
||||
extern int random_in_range( int minV, int maxV, MTdata d );
|
||||
|
||||
size_t get_random_size_t(size_t low, size_t high, MTdata d);
|
||||
|
||||
// Note: though this takes a double, this is for use with single precision tests
|
||||
static inline int IsFloatSubnormal( float x )
|
||||
{
|
||||
#if 2 == FLT_RADIX
|
||||
// Do this in integer to avoid problems with FTZ behavior
|
||||
union{ float d; uint32_t u;}u;
|
||||
u.d = fabsf(x);
|
||||
return (u.u-1) < 0x007fffffU;
|
||||
#else
|
||||
// rely on floating point hardware for non-radix2 non-IEEE-754 hardware -- will fail if you flush subnormals to zero
|
||||
return fabs(x) < (double) FLT_MIN && x != 0.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int IsDoubleSubnormal( double x )
|
||||
{
|
||||
#if 2 == FLT_RADIX
|
||||
// Do this in integer to avoid problems with FTZ behavior
|
||||
union{ double d; uint64_t u;}u;
|
||||
u.d = fabs( x);
|
||||
return (u.u-1) < 0x000fffffffffffffULL;
|
||||
#else
|
||||
// rely on floating point hardware for non-radix2 non-IEEE-754 hardware -- will fail if you flush subnormals to zero
|
||||
return fabs(x) < (double) DBL_MIN && x != 0.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _conversions_h
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,149 +1,149 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _errorHelpers_h
|
||||
#define _errorHelpers_h
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/opencl.h>
|
||||
#else
|
||||
#include <CL/opencl.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LOWER_IS_BETTER 0
|
||||
#define HIGHER_IS_BETTER 1
|
||||
|
||||
// If USE_ATF is defined, all log_error and log_info calls can be routed to test library
|
||||
// functions as described below. This is helpful for integration into an automated testing
|
||||
// system.
|
||||
#if USE_ATF
|
||||
// export BUILD_WITH_ATF=1
|
||||
#include <ATF/ATF.h>
|
||||
#define test_start() ATFTestStart()
|
||||
#define log_info ATFLogInfo
|
||||
#define log_error ATFLogError
|
||||
#define log_perf(_number, _higherBetter, _numType, _format, ...) ATFLogPerformanceNumber(_number, _higherBetter, _numType, _format, ##__VA_ARGS__)
|
||||
#define test_finish() ATFTestFinish()
|
||||
#define vlog_perf(_number, _higherBetter, _numType, _format, ...) ATFLogPerformanceNumber(_number, _higherBetter, _numType, _format,##__VA_ARGS__)
|
||||
#define vlog ATFLogInfo
|
||||
#define vlog_error ATFLogError
|
||||
#else
|
||||
#define test_start()
|
||||
#define log_info printf
|
||||
#define log_error printf
|
||||
#define log_perf(_number, _higherBetter, _numType, _format, ...) printf("Performance Number " _format " (in %s, %s): %g\n",##__VA_ARGS__, _numType, \
|
||||
_higherBetter?"higher is better":"lower is better", _number )
|
||||
#define test_finish()
|
||||
#define vlog_perf(_number, _higherBetter, _numType, _format, ...) printf("Performance Number " _format " (in %s, %s): %g\n",##__VA_ARGS__, _numType, \
|
||||
_higherBetter?"higher is better":"lower is better" , _number)
|
||||
#ifdef _WIN32
|
||||
#ifdef __MINGW32__
|
||||
// Use __mingw_printf since it supports "%a" format specifier
|
||||
#define vlog __mingw_printf
|
||||
#define vlog_error __mingw_printf
|
||||
#else
|
||||
// Use home-baked function that treats "%a" as "%f"
|
||||
static int vlog_win32(const char *format, ...);
|
||||
#define vlog vlog_win32
|
||||
#define vlog_error vlog_win32
|
||||
#endif
|
||||
#else
|
||||
#define vlog_error printf
|
||||
#define vlog printf
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ct_assert(b) ct_assert_i(b, __LINE__)
|
||||
#define ct_assert_i(b, line) ct_assert_ii(b, line)
|
||||
#define ct_assert_ii(b, line) int _compile_time_assertion_on_line_##line[b ? 1 : -1];
|
||||
|
||||
#define test_error(errCode,msg) test_error_ret(errCode,msg,errCode)
|
||||
#define test_error_ret(errCode,msg,retValue) { if( errCode != CL_SUCCESS ) { print_error( errCode, msg ); return retValue ; } }
|
||||
#define print_error(errCode,msg) log_error( "ERROR: %s! (%s from %s:%d)\n", msg, IGetErrorString( errCode ), __FILE__, __LINE__ );
|
||||
|
||||
// expected error code vs. what we got
|
||||
#define test_failure_error(errCode, expectedErrCode, msg) test_failure_error_ret(errCode, expectedErrCode, msg, errCode != expectedErrCode)
|
||||
#define test_failure_error_ret(errCode, expectedErrCode, msg, retValue) { if( errCode != expectedErrCode ) { print_failure_error( errCode, expectedErrCode, msg ); return retValue ; } }
|
||||
#define print_failure_error(errCode, expectedErrCode, msg) log_error( "ERROR: %s! (Got %s, expected %s from %s:%d)\n", msg, IGetErrorString( errCode ), IGetErrorString( expectedErrCode ), __FILE__, __LINE__ );
|
||||
#define test_failure_warning(errCode, expectedErrCode, msg) test_failure_warning_ret(errCode, expectedErrCode, msg, errCode != expectedErrCode)
|
||||
#define test_failure_warning_ret(errCode, expectedErrCode, msg, retValue) { if( errCode != expectedErrCode ) { print_failure_warning( errCode, expectedErrCode, msg ); warnings++ ; } }
|
||||
#define print_failure_warning(errCode, expectedErrCode, msg) log_error( "WARNING: %s! (Got %s, expected %s from %s:%d)\n", msg, IGetErrorString( errCode ), IGetErrorString( expectedErrCode ), __FILE__, __LINE__ );
|
||||
|
||||
extern const char *IGetErrorString( int clErrorCode );
|
||||
|
||||
extern float Ulp_Error_Half( cl_ushort test, float reference );
|
||||
extern float Ulp_Error( float test, double reference );
|
||||
extern float Ulp_Error_Double( double test, long double reference );
|
||||
|
||||
extern const char *GetChannelTypeName( cl_channel_type type );
|
||||
extern int IsChannelTypeSupported( cl_channel_type type );
|
||||
extern const char *GetChannelOrderName( cl_channel_order order );
|
||||
extern int IsChannelOrderSupported( cl_channel_order order );
|
||||
extern const char *GetAddressModeName( cl_addressing_mode mode );
|
||||
|
||||
extern const char *GetDeviceTypeName( cl_device_type type );
|
||||
|
||||
// NON-REENTRANT UNLESS YOU PROVIDE A BUFFER PTR (pass null to use static storage, but it's not reentrant then!)
|
||||
extern const char *GetDataVectorString( void *dataBuffer, size_t typeSize, size_t vecSize, char *buffer );
|
||||
|
||||
#if defined (_WIN32) && !defined(__MINGW32__)
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
static int vlog_win32(const char *format, ...)
|
||||
{
|
||||
const char *new_format = format;
|
||||
|
||||
if (strstr(format, "%a")) {
|
||||
char *temp;
|
||||
if ((temp = strdup(format)) == NULL) {
|
||||
printf("vlog_win32: Failed to allocate memory for strdup\n");
|
||||
return -1;
|
||||
}
|
||||
new_format = temp;
|
||||
while (*temp) {
|
||||
// replace %a with %f
|
||||
if ((*temp == '%') && (*(temp+1) == 'a')) {
|
||||
*(temp+1) = 'f';
|
||||
}
|
||||
temp++;
|
||||
}
|
||||
}
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vprintf(new_format, args);
|
||||
va_end(args);
|
||||
|
||||
if (new_format != format) {
|
||||
free((void*)new_format);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _errorHelpers_h
|
||||
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _errorHelpers_h
|
||||
#define _errorHelpers_h
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/opencl.h>
|
||||
#else
|
||||
#include <CL/opencl.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LOWER_IS_BETTER 0
|
||||
#define HIGHER_IS_BETTER 1
|
||||
|
||||
// If USE_ATF is defined, all log_error and log_info calls can be routed to test library
|
||||
// functions as described below. This is helpful for integration into an automated testing
|
||||
// system.
|
||||
#if USE_ATF
|
||||
// export BUILD_WITH_ATF=1
|
||||
#include <ATF/ATF.h>
|
||||
#define test_start() ATFTestStart()
|
||||
#define log_info ATFLogInfo
|
||||
#define log_error ATFLogError
|
||||
#define log_perf(_number, _higherBetter, _numType, _format, ...) ATFLogPerformanceNumber(_number, _higherBetter, _numType, _format, ##__VA_ARGS__)
|
||||
#define test_finish() ATFTestFinish()
|
||||
#define vlog_perf(_number, _higherBetter, _numType, _format, ...) ATFLogPerformanceNumber(_number, _higherBetter, _numType, _format,##__VA_ARGS__)
|
||||
#define vlog ATFLogInfo
|
||||
#define vlog_error ATFLogError
|
||||
#else
|
||||
#define test_start()
|
||||
#define log_info printf
|
||||
#define log_error printf
|
||||
#define log_perf(_number, _higherBetter, _numType, _format, ...) printf("Performance Number " _format " (in %s, %s): %g\n",##__VA_ARGS__, _numType, \
|
||||
_higherBetter?"higher is better":"lower is better", _number )
|
||||
#define test_finish()
|
||||
#define vlog_perf(_number, _higherBetter, _numType, _format, ...) printf("Performance Number " _format " (in %s, %s): %g\n",##__VA_ARGS__, _numType, \
|
||||
_higherBetter?"higher is better":"lower is better" , _number)
|
||||
#ifdef _WIN32
|
||||
#ifdef __MINGW32__
|
||||
// Use __mingw_printf since it supports "%a" format specifier
|
||||
#define vlog __mingw_printf
|
||||
#define vlog_error __mingw_printf
|
||||
#else
|
||||
// Use home-baked function that treats "%a" as "%f"
|
||||
static int vlog_win32(const char *format, ...);
|
||||
#define vlog vlog_win32
|
||||
#define vlog_error vlog_win32
|
||||
#endif
|
||||
#else
|
||||
#define vlog_error printf
|
||||
#define vlog printf
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ct_assert(b) ct_assert_i(b, __LINE__)
|
||||
#define ct_assert_i(b, line) ct_assert_ii(b, line)
|
||||
#define ct_assert_ii(b, line) int _compile_time_assertion_on_line_##line[b ? 1 : -1];
|
||||
|
||||
#define test_error(errCode,msg) test_error_ret(errCode,msg,errCode)
|
||||
#define test_error_ret(errCode,msg,retValue) { if( errCode != CL_SUCCESS ) { print_error( errCode, msg ); return retValue ; } }
|
||||
#define print_error(errCode,msg) log_error( "ERROR: %s! (%s from %s:%d)\n", msg, IGetErrorString( errCode ), __FILE__, __LINE__ );
|
||||
|
||||
// expected error code vs. what we got
|
||||
#define test_failure_error(errCode, expectedErrCode, msg) test_failure_error_ret(errCode, expectedErrCode, msg, errCode != expectedErrCode)
|
||||
#define test_failure_error_ret(errCode, expectedErrCode, msg, retValue) { if( errCode != expectedErrCode ) { print_failure_error( errCode, expectedErrCode, msg ); return retValue ; } }
|
||||
#define print_failure_error(errCode, expectedErrCode, msg) log_error( "ERROR: %s! (Got %s, expected %s from %s:%d)\n", msg, IGetErrorString( errCode ), IGetErrorString( expectedErrCode ), __FILE__, __LINE__ );
|
||||
#define test_failure_warning(errCode, expectedErrCode, msg) test_failure_warning_ret(errCode, expectedErrCode, msg, errCode != expectedErrCode)
|
||||
#define test_failure_warning_ret(errCode, expectedErrCode, msg, retValue) { if( errCode != expectedErrCode ) { print_failure_warning( errCode, expectedErrCode, msg ); warnings++ ; } }
|
||||
#define print_failure_warning(errCode, expectedErrCode, msg) log_error( "WARNING: %s! (Got %s, expected %s from %s:%d)\n", msg, IGetErrorString( errCode ), IGetErrorString( expectedErrCode ), __FILE__, __LINE__ );
|
||||
|
||||
extern const char *IGetErrorString( int clErrorCode );
|
||||
|
||||
extern float Ulp_Error_Half( cl_ushort test, float reference );
|
||||
extern float Ulp_Error( float test, double reference );
|
||||
extern float Ulp_Error_Double( double test, long double reference );
|
||||
|
||||
extern const char *GetChannelTypeName( cl_channel_type type );
|
||||
extern int IsChannelTypeSupported( cl_channel_type type );
|
||||
extern const char *GetChannelOrderName( cl_channel_order order );
|
||||
extern int IsChannelOrderSupported( cl_channel_order order );
|
||||
extern const char *GetAddressModeName( cl_addressing_mode mode );
|
||||
|
||||
extern const char *GetDeviceTypeName( cl_device_type type );
|
||||
|
||||
// NON-REENTRANT UNLESS YOU PROVIDE A BUFFER PTR (pass null to use static storage, but it's not reentrant then!)
|
||||
extern const char *GetDataVectorString( void *dataBuffer, size_t typeSize, size_t vecSize, char *buffer );
|
||||
|
||||
#if defined (_WIN32) && !defined(__MINGW32__)
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
static int vlog_win32(const char *format, ...)
|
||||
{
|
||||
const char *new_format = format;
|
||||
|
||||
if (strstr(format, "%a")) {
|
||||
char *temp;
|
||||
if ((temp = strdup(format)) == NULL) {
|
||||
printf("vlog_win32: Failed to allocate memory for strdup\n");
|
||||
return -1;
|
||||
}
|
||||
new_format = temp;
|
||||
while (*temp) {
|
||||
// replace %a with %f
|
||||
if ((*temp == '%') && (*(temp+1) == 'a')) {
|
||||
*(temp+1) = 'f';
|
||||
}
|
||||
temp++;
|
||||
}
|
||||
}
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vprintf(new_format, args);
|
||||
va_end(args);
|
||||
|
||||
if (new_format != format) {
|
||||
free((void*)new_format);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _errorHelpers_h
|
||||
|
||||
|
||||
|
||||
@@ -1,89 +1,104 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _fpcontrol_h
|
||||
#define _fpcontrol_h
|
||||
|
||||
// In order to get tests for correctly rounded operations (e.g. multiply) to work properly we need to be able to set the reference hardware
|
||||
// to FTZ mode if the device hardware is running in that mode. We have explored all other options short of writing correctly rounded operations
|
||||
// in integer code, and have found this is the only way to correctly verify operation.
|
||||
//
|
||||
// Non-Apple implementations will need to provide their own implentation for these features. If the reference hardware and device are both
|
||||
// running in the same state (either FTZ or IEEE compliant modes) then these functions may be empty. If the device is running in non-default
|
||||
// rounding mode (e.g. round toward zero), then these functions should also set the reference device into that rounding mode.
|
||||
#if defined( __APPLE__ ) || defined( _MSC_VER ) || defined( __linux__ ) || defined (__MINGW32__)
|
||||
typedef int FPU_mode_type;
|
||||
#if defined( __i386__ ) || defined( __x86_64__ )
|
||||
#include <xmmintrin.h>
|
||||
#elif defined( __PPC__ )
|
||||
#include <fpu_control.h>
|
||||
extern __thread fpu_control_t fpu_control;
|
||||
#endif
|
||||
// Set the reference hardware floating point unit to FTZ mode
|
||||
static inline void ForceFTZ( FPU_mode_type *mode )
|
||||
{
|
||||
#if defined( __i386__ ) || defined( __x86_64__ ) || defined( _MSC_VER ) || defined (__MINGW32__)
|
||||
*mode = _mm_getcsr();
|
||||
_mm_setcsr( *mode | 0x8040);
|
||||
#elif defined( __PPC__ )
|
||||
*mode = fpu_control;
|
||||
fpu_control |= _FPU_MASK_NI;
|
||||
#elif defined ( __arm__ )
|
||||
unsigned fpscr;
|
||||
__asm__ volatile ("fmrx %0, fpscr" : "=r"(fpscr));
|
||||
*mode = fpscr;
|
||||
__asm__ volatile ("fmxr fpscr, %0" :: "r"(fpscr | (1U << 24)));
|
||||
#else
|
||||
#error ForceFTZ needs an implentation
|
||||
#endif
|
||||
}
|
||||
|
||||
// Disable the denorm flush to zero
|
||||
static inline void DisableFTZ( FPU_mode_type *mode )
|
||||
{
|
||||
#if defined( __i386__ ) || defined( __x86_64__ ) || defined( _MSC_VER ) || defined (__MINGW32__)
|
||||
*mode = _mm_getcsr();
|
||||
_mm_setcsr( *mode & ~0x8040);
|
||||
#elif defined( __PPC__ )
|
||||
*mode = fpu_control;
|
||||
fpu_control &= ~_FPU_MASK_NI;
|
||||
#elif defined ( __arm__ )
|
||||
unsigned fpscr;
|
||||
__asm__ volatile ("fmrx %0, fpscr" : "=r"(fpscr));
|
||||
*mode = fpscr;
|
||||
__asm__ volatile ("fmxr fpscr, %0" :: "r"(fpscr & ~(1U << 24)));
|
||||
#else
|
||||
#error DisableFTZ needs an implentation
|
||||
#endif
|
||||
}
|
||||
|
||||
// Restore the reference hardware to floating point state indicated by *mode
|
||||
static inline void RestoreFPState( FPU_mode_type *mode )
|
||||
{
|
||||
#if defined( __i386__ ) || defined( __x86_64__ ) || defined( _MSC_VER ) || defined (__MINGW32__)
|
||||
_mm_setcsr( *mode );
|
||||
#elif defined( __PPC__)
|
||||
fpu_control = *mode;
|
||||
#elif defined (__arm__)
|
||||
__asm__ volatile ("fmxr fpscr, %0" :: "r"(*mode));
|
||||
#else
|
||||
#error RestoreFPState needs an implementation
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
#error ForceFTZ and RestoreFPState need implentations
|
||||
#endif
|
||||
|
||||
#endif
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _fpcontrol_h
|
||||
#define _fpcontrol_h
|
||||
|
||||
// In order to get tests for correctly rounded operations (e.g. multiply) to work properly we need to be able to set the reference hardware
|
||||
// to FTZ mode if the device hardware is running in that mode. We have explored all other options short of writing correctly rounded operations
|
||||
// in integer code, and have found this is the only way to correctly verify operation.
|
||||
//
|
||||
// Non-Apple implementations will need to provide their own implentation for these features. If the reference hardware and device are both
|
||||
// running in the same state (either FTZ or IEEE compliant modes) then these functions may be empty. If the device is running in non-default
|
||||
// rounding mode (e.g. round toward zero), then these functions should also set the reference device into that rounding mode.
|
||||
#if defined( __APPLE__ ) || defined( _MSC_VER ) || defined( __linux__ ) || defined (__MINGW32__)
|
||||
typedef int FPU_mode_type;
|
||||
#if defined( __i386__ ) || defined( __x86_64__ ) || defined( _MSC_VER ) || defined( __MINGW32__ )
|
||||
#include <xmmintrin.h>
|
||||
#elif defined( __PPC__ )
|
||||
#include <fpu_control.h>
|
||||
extern __thread fpu_control_t fpu_control;
|
||||
#endif
|
||||
// Set the reference hardware floating point unit to FTZ mode
|
||||
static inline void ForceFTZ( FPU_mode_type *mode )
|
||||
{
|
||||
#if defined( __i386__ ) || defined( __x86_64__ ) || defined( _MSC_VER ) || defined (__MINGW32__)
|
||||
*mode = _mm_getcsr();
|
||||
_mm_setcsr( *mode | 0x8040);
|
||||
#elif defined( __PPC__ )
|
||||
*mode = fpu_control;
|
||||
fpu_control |= _FPU_MASK_NI;
|
||||
#elif defined ( __arm__ )
|
||||
unsigned fpscr;
|
||||
__asm__ volatile ("fmrx %0, fpscr" : "=r"(fpscr));
|
||||
*mode = fpscr;
|
||||
__asm__ volatile ("fmxr fpscr, %0" :: "r"(fpscr | (1U << 24)));
|
||||
// Add 64 bit support
|
||||
#elif defined (__aarch64__)
|
||||
unsigned fpcr;
|
||||
__asm__ volatile ("mrs %0, fpcr" : "=r"(fpcr));
|
||||
*mode = fpcr;
|
||||
__asm__ volatile ("msr fpcr, %0" :: "r"(fpcr | (1U << 24)));
|
||||
#else
|
||||
#error ForceFTZ needs an implentation
|
||||
#endif
|
||||
}
|
||||
|
||||
// Disable the denorm flush to zero
|
||||
static inline void DisableFTZ( FPU_mode_type *mode )
|
||||
{
|
||||
#if defined( __i386__ ) || defined( __x86_64__ ) || defined( _MSC_VER ) || defined (__MINGW32__)
|
||||
*mode = _mm_getcsr();
|
||||
_mm_setcsr( *mode & ~0x8040);
|
||||
#elif defined( __PPC__ )
|
||||
*mode = fpu_control;
|
||||
fpu_control &= ~_FPU_MASK_NI;
|
||||
#elif defined ( __arm__ )
|
||||
unsigned fpscr;
|
||||
__asm__ volatile ("fmrx %0, fpscr" : "=r"(fpscr));
|
||||
*mode = fpscr;
|
||||
__asm__ volatile ("fmxr fpscr, %0" :: "r"(fpscr & ~(1U << 24)));
|
||||
// Add 64 bit support
|
||||
#elif defined (__aarch64__)
|
||||
unsigned fpcr;
|
||||
__asm__ volatile ("mrs %0, fpcr" : "=r"(fpcr));
|
||||
*mode = fpcr;
|
||||
__asm__ volatile ("msr fpcr, %0" :: "r"(fpcr & ~(1U << 24)));
|
||||
#else
|
||||
#error DisableFTZ needs an implentation
|
||||
#endif
|
||||
}
|
||||
|
||||
// Restore the reference hardware to floating point state indicated by *mode
|
||||
static inline void RestoreFPState( FPU_mode_type *mode )
|
||||
{
|
||||
#if defined( __i386__ ) || defined( __x86_64__ ) || defined( _MSC_VER ) || defined (__MINGW32__)
|
||||
_mm_setcsr( *mode );
|
||||
#elif defined( __PPC__)
|
||||
fpu_control = *mode;
|
||||
#elif defined (__arm__)
|
||||
__asm__ volatile ("fmxr fpscr, %0" :: "r"(*mode));
|
||||
// Add 64 bit support
|
||||
#elif defined (__aarch64__)
|
||||
__asm__ volatile ("msr fpcr, %0" :: "r"(*mode));
|
||||
#else
|
||||
#error RestoreFPState needs an implementation
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
#error ForceFTZ and RestoreFPState need implentations
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,53 +1,53 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "genericThread.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#else // !_WIN32
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
void * genericThread::IStaticReflector( void * data )
|
||||
{
|
||||
genericThread *t = (genericThread *)data;
|
||||
return t->IRun();
|
||||
}
|
||||
|
||||
bool genericThread::Start( void )
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
mHandle = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) IStaticReflector, this, 0, NULL );
|
||||
return ( mHandle != NULL );
|
||||
#else // !_WIN32
|
||||
int error = pthread_create( (pthread_t*)&mHandle, NULL, IStaticReflector, (void *)this );
|
||||
return ( error == 0 );
|
||||
#endif // !_WIN32
|
||||
}
|
||||
|
||||
void * genericThread::Join( void )
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
WaitForSingleObject( (HANDLE)mHandle, INFINITE );
|
||||
return NULL;
|
||||
#else // !_WIN32
|
||||
void * retVal;
|
||||
int error = pthread_join( (pthread_t)mHandle, &retVal );
|
||||
if( error != 0 )
|
||||
retVal = NULL;
|
||||
return retVal;
|
||||
#endif // !_WIN32
|
||||
}
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "genericThread.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#else // !_WIN32
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
void * genericThread::IStaticReflector( void * data )
|
||||
{
|
||||
genericThread *t = (genericThread *)data;
|
||||
return t->IRun();
|
||||
}
|
||||
|
||||
bool genericThread::Start( void )
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
mHandle = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) IStaticReflector, this, 0, NULL );
|
||||
return ( mHandle != NULL );
|
||||
#else // !_WIN32
|
||||
int error = pthread_create( (pthread_t*)&mHandle, NULL, IStaticReflector, (void *)this );
|
||||
return ( error == 0 );
|
||||
#endif // !_WIN32
|
||||
}
|
||||
|
||||
void * genericThread::Join( void )
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
WaitForSingleObject( (HANDLE)mHandle, INFINITE );
|
||||
return NULL;
|
||||
#else // !_WIN32
|
||||
void * retVal;
|
||||
int error = pthread_join( (pthread_t)mHandle, &retVal );
|
||||
if( error != 0 )
|
||||
retVal = NULL;
|
||||
return retVal;
|
||||
#endif // !_WIN32
|
||||
}
|
||||
|
||||
@@ -1,42 +1,42 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _genericThread_h
|
||||
#define _genericThread_h
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
class genericThread
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~genericThread() {}
|
||||
|
||||
bool Start( void );
|
||||
void * Join( void );
|
||||
|
||||
protected:
|
||||
|
||||
virtual void * IRun( void ) = 0;
|
||||
|
||||
private:
|
||||
|
||||
void* mHandle;
|
||||
|
||||
static void * IStaticReflector( void * data );
|
||||
};
|
||||
|
||||
#endif // _genericThread_h
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _genericThread_h
|
||||
#define _genericThread_h
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
class genericThread
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~genericThread() {}
|
||||
|
||||
bool Start( void );
|
||||
void * Join( void );
|
||||
|
||||
protected:
|
||||
|
||||
virtual void * IRun( void ) = 0;
|
||||
|
||||
private:
|
||||
|
||||
void* mHandle;
|
||||
|
||||
static void * IStaticReflector( void * data );
|
||||
};
|
||||
|
||||
#endif // _genericThread_h
|
||||
|
||||
|
||||
@@ -1,249 +1,249 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "imageHelpers.h"
|
||||
|
||||
size_t get_format_type_size( const cl_image_format *format )
|
||||
{
|
||||
return get_channel_data_type_size( format->image_channel_data_type );
|
||||
}
|
||||
|
||||
size_t get_channel_data_type_size( cl_channel_type channelType )
|
||||
{
|
||||
switch( channelType )
|
||||
{
|
||||
case CL_SNORM_INT8:
|
||||
case CL_UNORM_INT8:
|
||||
case CL_SIGNED_INT8:
|
||||
case CL_UNSIGNED_INT8:
|
||||
return 1;
|
||||
|
||||
case CL_SNORM_INT16:
|
||||
case CL_UNORM_INT16:
|
||||
case CL_SIGNED_INT16:
|
||||
case CL_UNSIGNED_INT16:
|
||||
case CL_HALF_FLOAT:
|
||||
#ifdef CL_SFIXED14_APPLE
|
||||
case CL_SFIXED14_APPLE:
|
||||
#endif
|
||||
return sizeof( cl_short );
|
||||
|
||||
case CL_SIGNED_INT32:
|
||||
case CL_UNSIGNED_INT32:
|
||||
return sizeof( cl_int );
|
||||
|
||||
case CL_UNORM_SHORT_565:
|
||||
case CL_UNORM_SHORT_555:
|
||||
#ifdef OBSOLETE_FORAMT
|
||||
case CL_UNORM_SHORT_565_REV:
|
||||
case CL_UNORM_SHORT_555_REV:
|
||||
#endif
|
||||
return 2;
|
||||
|
||||
#ifdef OBSOLETE_FORAMT
|
||||
case CL_UNORM_INT_8888:
|
||||
case CL_UNORM_INT_8888_REV:
|
||||
return 4;
|
||||
#endif
|
||||
|
||||
case CL_UNORM_INT_101010:
|
||||
#ifdef OBSOLETE_FORAMT
|
||||
case CL_UNORM_INT_101010_REV:
|
||||
#endif
|
||||
return 4;
|
||||
|
||||
case CL_FLOAT:
|
||||
return sizeof( cl_float );
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t get_format_channel_count( const cl_image_format *format )
|
||||
{
|
||||
return get_channel_order_channel_count( format->image_channel_order );
|
||||
}
|
||||
|
||||
size_t get_channel_order_channel_count( cl_channel_order order )
|
||||
{
|
||||
switch( order )
|
||||
{
|
||||
case CL_R:
|
||||
case CL_A:
|
||||
case CL_Rx:
|
||||
case CL_INTENSITY:
|
||||
case CL_LUMINANCE:
|
||||
return 1;
|
||||
|
||||
case CL_RG:
|
||||
case CL_RA:
|
||||
case CL_RGx:
|
||||
return 2;
|
||||
|
||||
case CL_RGB:
|
||||
case CL_RGBx:
|
||||
return 3;
|
||||
|
||||
case CL_RGBA:
|
||||
case CL_ARGB:
|
||||
case CL_BGRA:
|
||||
#ifdef CL_1RGB_APPLE
|
||||
case CL_1RGB_APPLE:
|
||||
#endif
|
||||
#ifdef CL_BGR1_APPLE
|
||||
case CL_BGR1_APPLE:
|
||||
#endif
|
||||
return 4;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int is_format_signed( const cl_image_format *format )
|
||||
{
|
||||
switch( format->image_channel_data_type )
|
||||
{
|
||||
case CL_SNORM_INT8:
|
||||
case CL_SIGNED_INT8:
|
||||
case CL_SNORM_INT16:
|
||||
case CL_SIGNED_INT16:
|
||||
case CL_SIGNED_INT32:
|
||||
case CL_HALF_FLOAT:
|
||||
case CL_FLOAT:
|
||||
#ifdef CL_SFIXED14_APPLE
|
||||
case CL_SFIXED14_APPLE:
|
||||
#endif
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t get_pixel_size( cl_image_format *format )
|
||||
{
|
||||
switch( format->image_channel_data_type )
|
||||
{
|
||||
case CL_SNORM_INT8:
|
||||
case CL_UNORM_INT8:
|
||||
case CL_SIGNED_INT8:
|
||||
case CL_UNSIGNED_INT8:
|
||||
return get_format_channel_count( format );
|
||||
|
||||
case CL_SNORM_INT16:
|
||||
case CL_UNORM_INT16:
|
||||
case CL_SIGNED_INT16:
|
||||
case CL_UNSIGNED_INT16:
|
||||
case CL_HALF_FLOAT:
|
||||
#ifdef CL_SFIXED14_APPLE
|
||||
case CL_SFIXED14_APPLE:
|
||||
#endif
|
||||
return get_format_channel_count( format ) * sizeof( cl_ushort );
|
||||
|
||||
case CL_SIGNED_INT32:
|
||||
case CL_UNSIGNED_INT32:
|
||||
return get_format_channel_count( format ) * sizeof( cl_int );
|
||||
|
||||
case CL_UNORM_SHORT_565:
|
||||
case CL_UNORM_SHORT_555:
|
||||
#ifdef OBSOLETE_FORAMT
|
||||
case CL_UNORM_SHORT_565_REV:
|
||||
case CL_UNORM_SHORT_555_REV:
|
||||
#endif
|
||||
return 2;
|
||||
|
||||
#ifdef OBSOLETE_FORAMT
|
||||
case CL_UNORM_INT_8888:
|
||||
case CL_UNORM_INT_8888_REV:
|
||||
return 4;
|
||||
#endif
|
||||
|
||||
case CL_UNORM_INT_101010:
|
||||
#ifdef OBSOLETE_FORAMT
|
||||
case CL_UNORM_INT_101010_REV:
|
||||
#endif
|
||||
return 4;
|
||||
|
||||
case CL_FLOAT:
|
||||
return get_format_channel_count( format ) * sizeof( cl_float );
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int get_8_bit_image_format( cl_context context, cl_mem_object_type objType, cl_mem_flags flags, size_t channelCount, cl_image_format *outFormat )
|
||||
{
|
||||
cl_image_format formatList[ 128 ];
|
||||
unsigned int outFormatCount, i;
|
||||
int error;
|
||||
|
||||
|
||||
/* Make sure each image format is supported */
|
||||
if ((error = clGetSupportedImageFormats( context, flags, objType, 128, formatList, &outFormatCount )))
|
||||
return error;
|
||||
|
||||
|
||||
/* Look for one that is an 8-bit format */
|
||||
for( i = 0; i < outFormatCount; i++ )
|
||||
{
|
||||
if( formatList[ i ].image_channel_data_type == CL_SNORM_INT8 ||
|
||||
formatList[ i ].image_channel_data_type == CL_UNORM_INT8 ||
|
||||
formatList[ i ].image_channel_data_type == CL_SIGNED_INT8 ||
|
||||
formatList[ i ].image_channel_data_type == CL_UNSIGNED_INT8 )
|
||||
{
|
||||
if ( !channelCount || ( channelCount && ( get_format_channel_count( &formatList[ i ] ) == channelCount ) ) )
|
||||
{
|
||||
*outFormat = formatList[ i ];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int get_32_bit_image_format( cl_context context, cl_mem_object_type objType, cl_mem_flags flags, size_t channelCount, cl_image_format *outFormat )
|
||||
{
|
||||
cl_image_format formatList[ 128 ];
|
||||
unsigned int outFormatCount, i;
|
||||
int error;
|
||||
|
||||
|
||||
/* Make sure each image format is supported */
|
||||
if ((error = clGetSupportedImageFormats( context, flags, objType, 128, formatList, &outFormatCount )))
|
||||
return error;
|
||||
|
||||
/* Look for one that is an 8-bit format */
|
||||
for( i = 0; i < outFormatCount; i++ )
|
||||
{
|
||||
if( formatList[ i ].image_channel_data_type == CL_UNORM_INT_101010 ||
|
||||
formatList[ i ].image_channel_data_type == CL_FLOAT ||
|
||||
formatList[ i ].image_channel_data_type == CL_SIGNED_INT32 ||
|
||||
formatList[ i ].image_channel_data_type == CL_UNSIGNED_INT32 )
|
||||
{
|
||||
if ( !channelCount || ( channelCount && ( get_format_channel_count( &formatList[ i ] ) == channelCount ) ) )
|
||||
{
|
||||
*outFormat = formatList[ i ];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "imageHelpers.h"
|
||||
|
||||
size_t get_format_type_size( const cl_image_format *format )
|
||||
{
|
||||
return get_channel_data_type_size( format->image_channel_data_type );
|
||||
}
|
||||
|
||||
size_t get_channel_data_type_size( cl_channel_type channelType )
|
||||
{
|
||||
switch( channelType )
|
||||
{
|
||||
case CL_SNORM_INT8:
|
||||
case CL_UNORM_INT8:
|
||||
case CL_SIGNED_INT8:
|
||||
case CL_UNSIGNED_INT8:
|
||||
return 1;
|
||||
|
||||
case CL_SNORM_INT16:
|
||||
case CL_UNORM_INT16:
|
||||
case CL_SIGNED_INT16:
|
||||
case CL_UNSIGNED_INT16:
|
||||
case CL_HALF_FLOAT:
|
||||
#ifdef CL_SFIXED14_APPLE
|
||||
case CL_SFIXED14_APPLE:
|
||||
#endif
|
||||
return sizeof( cl_short );
|
||||
|
||||
case CL_SIGNED_INT32:
|
||||
case CL_UNSIGNED_INT32:
|
||||
return sizeof( cl_int );
|
||||
|
||||
case CL_UNORM_SHORT_565:
|
||||
case CL_UNORM_SHORT_555:
|
||||
#ifdef OBSOLETE_FORAMT
|
||||
case CL_UNORM_SHORT_565_REV:
|
||||
case CL_UNORM_SHORT_555_REV:
|
||||
#endif
|
||||
return 2;
|
||||
|
||||
#ifdef OBSOLETE_FORAMT
|
||||
case CL_UNORM_INT_8888:
|
||||
case CL_UNORM_INT_8888_REV:
|
||||
return 4;
|
||||
#endif
|
||||
|
||||
case CL_UNORM_INT_101010:
|
||||
#ifdef OBSOLETE_FORAMT
|
||||
case CL_UNORM_INT_101010_REV:
|
||||
#endif
|
||||
return 4;
|
||||
|
||||
case CL_FLOAT:
|
||||
return sizeof( cl_float );
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t get_format_channel_count( const cl_image_format *format )
|
||||
{
|
||||
return get_channel_order_channel_count( format->image_channel_order );
|
||||
}
|
||||
|
||||
size_t get_channel_order_channel_count( cl_channel_order order )
|
||||
{
|
||||
switch( order )
|
||||
{
|
||||
case CL_R:
|
||||
case CL_A:
|
||||
case CL_Rx:
|
||||
case CL_INTENSITY:
|
||||
case CL_LUMINANCE:
|
||||
return 1;
|
||||
|
||||
case CL_RG:
|
||||
case CL_RA:
|
||||
case CL_RGx:
|
||||
return 2;
|
||||
|
||||
case CL_RGB:
|
||||
case CL_RGBx:
|
||||
return 3;
|
||||
|
||||
case CL_RGBA:
|
||||
case CL_ARGB:
|
||||
case CL_BGRA:
|
||||
#ifdef CL_1RGB_APPLE
|
||||
case CL_1RGB_APPLE:
|
||||
#endif
|
||||
#ifdef CL_BGR1_APPLE
|
||||
case CL_BGR1_APPLE:
|
||||
#endif
|
||||
return 4;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int is_format_signed( const cl_image_format *format )
|
||||
{
|
||||
switch( format->image_channel_data_type )
|
||||
{
|
||||
case CL_SNORM_INT8:
|
||||
case CL_SIGNED_INT8:
|
||||
case CL_SNORM_INT16:
|
||||
case CL_SIGNED_INT16:
|
||||
case CL_SIGNED_INT32:
|
||||
case CL_HALF_FLOAT:
|
||||
case CL_FLOAT:
|
||||
#ifdef CL_SFIXED14_APPLE
|
||||
case CL_SFIXED14_APPLE:
|
||||
#endif
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t get_pixel_size( cl_image_format *format )
|
||||
{
|
||||
switch( format->image_channel_data_type )
|
||||
{
|
||||
case CL_SNORM_INT8:
|
||||
case CL_UNORM_INT8:
|
||||
case CL_SIGNED_INT8:
|
||||
case CL_UNSIGNED_INT8:
|
||||
return get_format_channel_count( format );
|
||||
|
||||
case CL_SNORM_INT16:
|
||||
case CL_UNORM_INT16:
|
||||
case CL_SIGNED_INT16:
|
||||
case CL_UNSIGNED_INT16:
|
||||
case CL_HALF_FLOAT:
|
||||
#ifdef CL_SFIXED14_APPLE
|
||||
case CL_SFIXED14_APPLE:
|
||||
#endif
|
||||
return get_format_channel_count( format ) * sizeof( cl_ushort );
|
||||
|
||||
case CL_SIGNED_INT32:
|
||||
case CL_UNSIGNED_INT32:
|
||||
return get_format_channel_count( format ) * sizeof( cl_int );
|
||||
|
||||
case CL_UNORM_SHORT_565:
|
||||
case CL_UNORM_SHORT_555:
|
||||
#ifdef OBSOLETE_FORAMT
|
||||
case CL_UNORM_SHORT_565_REV:
|
||||
case CL_UNORM_SHORT_555_REV:
|
||||
#endif
|
||||
return 2;
|
||||
|
||||
#ifdef OBSOLETE_FORAMT
|
||||
case CL_UNORM_INT_8888:
|
||||
case CL_UNORM_INT_8888_REV:
|
||||
return 4;
|
||||
#endif
|
||||
|
||||
case CL_UNORM_INT_101010:
|
||||
#ifdef OBSOLETE_FORAMT
|
||||
case CL_UNORM_INT_101010_REV:
|
||||
#endif
|
||||
return 4;
|
||||
|
||||
case CL_FLOAT:
|
||||
return get_format_channel_count( format ) * sizeof( cl_float );
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int get_8_bit_image_format( cl_context context, cl_mem_object_type objType, cl_mem_flags flags, size_t channelCount, cl_image_format *outFormat )
|
||||
{
|
||||
cl_image_format formatList[ 128 ];
|
||||
unsigned int outFormatCount, i;
|
||||
int error;
|
||||
|
||||
|
||||
/* Make sure each image format is supported */
|
||||
if ((error = clGetSupportedImageFormats( context, flags, objType, 128, formatList, &outFormatCount )))
|
||||
return error;
|
||||
|
||||
|
||||
/* Look for one that is an 8-bit format */
|
||||
for( i = 0; i < outFormatCount; i++ )
|
||||
{
|
||||
if( formatList[ i ].image_channel_data_type == CL_SNORM_INT8 ||
|
||||
formatList[ i ].image_channel_data_type == CL_UNORM_INT8 ||
|
||||
formatList[ i ].image_channel_data_type == CL_SIGNED_INT8 ||
|
||||
formatList[ i ].image_channel_data_type == CL_UNSIGNED_INT8 )
|
||||
{
|
||||
if ( !channelCount || ( channelCount && ( get_format_channel_count( &formatList[ i ] ) == channelCount ) ) )
|
||||
{
|
||||
*outFormat = formatList[ i ];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int get_32_bit_image_format( cl_context context, cl_mem_object_type objType, cl_mem_flags flags, size_t channelCount, cl_image_format *outFormat )
|
||||
{
|
||||
cl_image_format formatList[ 128 ];
|
||||
unsigned int outFormatCount, i;
|
||||
int error;
|
||||
|
||||
|
||||
/* Make sure each image format is supported */
|
||||
if ((error = clGetSupportedImageFormats( context, flags, objType, 128, formatList, &outFormatCount )))
|
||||
return error;
|
||||
|
||||
/* Look for one that is an 8-bit format */
|
||||
for( i = 0; i < outFormatCount; i++ )
|
||||
{
|
||||
if( formatList[ i ].image_channel_data_type == CL_UNORM_INT_101010 ||
|
||||
formatList[ i ].image_channel_data_type == CL_FLOAT ||
|
||||
formatList[ i ].image_channel_data_type == CL_SIGNED_INT32 ||
|
||||
formatList[ i ].image_channel_data_type == CL_UNSIGNED_INT32 )
|
||||
{
|
||||
if ( !channelCount || ( channelCount && ( get_format_channel_count( &formatList[ i ] ) == channelCount ) ) )
|
||||
{
|
||||
*outFormat = formatList[ i ];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _imageHelpers_h
|
||||
#define _imageHelpers_h
|
||||
|
||||
#include "errorHelpers.h"
|
||||
|
||||
|
||||
extern size_t get_format_type_size( const cl_image_format *format );
|
||||
extern size_t get_channel_data_type_size( cl_channel_type channelType );
|
||||
extern size_t get_format_channel_count( const cl_image_format *format );
|
||||
extern size_t get_channel_order_channel_count( cl_channel_order order );
|
||||
extern int is_format_signed( const cl_image_format *format );
|
||||
extern size_t get_pixel_size( cl_image_format *format );
|
||||
|
||||
/* Helper to get any ol image format as long as it is 8-bits-per-channel */
|
||||
extern int get_8_bit_image_format( cl_context context, cl_mem_object_type objType, cl_mem_flags flags, size_t channelCount, cl_image_format *outFormat );
|
||||
|
||||
/* Helper to get any ol image format as long as it is 32-bits-per-channel */
|
||||
extern int get_32_bit_image_format( cl_context context, cl_mem_object_type objType, cl_mem_flags flags, size_t channelCount, cl_image_format *outFormat );
|
||||
|
||||
|
||||
#endif // _imageHelpers_h
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _imageHelpers_h
|
||||
#define _imageHelpers_h
|
||||
|
||||
#include "errorHelpers.h"
|
||||
|
||||
|
||||
extern size_t get_format_type_size( const cl_image_format *format );
|
||||
extern size_t get_channel_data_type_size( cl_channel_type channelType );
|
||||
extern size_t get_format_channel_count( const cl_image_format *format );
|
||||
extern size_t get_channel_order_channel_count( cl_channel_order order );
|
||||
extern int is_format_signed( const cl_image_format *format );
|
||||
extern size_t get_pixel_size( cl_image_format *format );
|
||||
|
||||
/* Helper to get any ol image format as long as it is 8-bits-per-channel */
|
||||
extern int get_8_bit_image_format( cl_context context, cl_mem_object_type objType, cl_mem_flags flags, size_t channelCount, cl_image_format *outFormat );
|
||||
|
||||
/* Helper to get any ol image format as long as it is 32-bits-per-channel */
|
||||
extern int get_32_bit_image_format( cl_context context, cl_mem_object_type objType, cl_mem_flags flags, size_t channelCount, cl_image_format *outFormat );
|
||||
|
||||
|
||||
#endif // _imageHelpers_h
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,131 +1,131 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _kernelHelpers_h
|
||||
#define _kernelHelpers_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined (__MINGW32__)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/opencl.h>
|
||||
#else
|
||||
#include <CL/opencl.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
/*
|
||||
* The below code is intended to be used at the top of kernels that appear inline in files to set line and file info for the kernel:
|
||||
*
|
||||
* const char *source = {
|
||||
* INIT_OPENCL_DEBUG_INFO
|
||||
* "__kernel void foo( int x )\n"
|
||||
* "{\n"
|
||||
* " ...\n"
|
||||
* "}\n"
|
||||
* };
|
||||
*/
|
||||
#define INIT_OPENCL_DEBUG_INFO SET_OPENCL_LINE_INFO( __LINE__, __FILE__ )
|
||||
#define SET_OPENCL_LINE_INFO(_line, _file) "#line " STRINGIFY(_line) " " STRINGIFY(_file) "\n"
|
||||
#ifndef STRINGIFY_VALUE
|
||||
#define STRINGIFY_VALUE(_x) STRINGIFY(_x)
|
||||
#endif
|
||||
#ifndef STRINGIFY
|
||||
#define STRINGIFY(_x) #_x
|
||||
#endif
|
||||
|
||||
/* Helper that creates a single program and kernel from a single-kernel program source */
|
||||
extern int create_single_kernel_helper( cl_context context, cl_program *outProgram, cl_kernel *outKernel, unsigned int numKernelLines, const char **kernelProgram, const char *kernelName );
|
||||
|
||||
/* Helper to obtain the biggest fit work group size for all the devices in a given group and for the given global thread size */
|
||||
extern int get_max_common_work_group_size( cl_context context, cl_kernel kernel, size_t globalThreadSize, size_t *outSize );
|
||||
|
||||
/* Helper to obtain the biggest fit work group size for all the devices in a given group and for the given global thread size */
|
||||
extern int get_max_common_2D_work_group_size( cl_context context, cl_kernel kernel, size_t *globalThreadSize, size_t *outSizes );
|
||||
|
||||
/* Helper to obtain the biggest fit work group size for all the devices in a given group and for the given global thread size */
|
||||
extern int get_max_common_3D_work_group_size( cl_context context, cl_kernel kernel, size_t *globalThreadSize, size_t *outSizes );
|
||||
|
||||
/* Helper to get major/minor number for a device */
|
||||
extern int get_device_version( cl_device_id id, size_t* major, size_t* minor);
|
||||
|
||||
/* Helper to obtain the biggest allowed work group size for all the devices in a given group */
|
||||
extern int get_max_allowed_work_group_size( cl_context context, cl_kernel kernel, size_t *outSize, size_t *outLimits );
|
||||
|
||||
/* Helper to determine if an extension is supported by a device */
|
||||
extern int is_extension_available( cl_device_id device, const char *extensionName );
|
||||
|
||||
/* Helper to determine if a device supports an image format */
|
||||
extern int is_image_format_supported( cl_context context, cl_mem_flags flags, cl_mem_object_type image_type, const cl_image_format *fmt );
|
||||
|
||||
/* Helper to get pixel size for a pixel format */
|
||||
size_t get_pixel_bytes( const cl_image_format *fmt );
|
||||
|
||||
/* Verify the given device supports images. 0 means you're good to go, otherwise an error */
|
||||
extern int verifyImageSupport( cl_device_id device );
|
||||
|
||||
/* Checks that the given device supports images. Same as verify, but doesn't print an error */
|
||||
extern int checkForImageSupport( cl_device_id device );
|
||||
extern int checkFor3DImageSupport( cl_device_id device );
|
||||
|
||||
/* Checks that a given queue property is supported on the specified device. Returns 1 if supported, 0 if not or an error. */
|
||||
extern int checkDeviceForQueueSupport( cl_device_id device, cl_command_queue_properties prop );
|
||||
|
||||
/* Helper for aligned memory allocation */
|
||||
void * align_malloc(size_t size, size_t alignment);
|
||||
void align_free(void *);
|
||||
|
||||
/* Helper to obtain the min alignment for a given context, i.e the max of all min alignments for devices attached to the context*/
|
||||
size_t get_min_alignment(cl_context context);
|
||||
|
||||
/* Helper to obtain the default rounding mode for single precision computation. (Double is always CL_FP_ROUND_TO_NEAREST.) Returns 0 on error. */
|
||||
cl_device_fp_config get_default_rounding_mode( cl_device_id device );
|
||||
|
||||
#define PASSIVE_REQUIRE_IMAGE_SUPPORT( device ) \
|
||||
if( checkForImageSupport( device ) ) \
|
||||
{ \
|
||||
log_info( "\n\tNote: device does not support images. Skipping test...\n" ); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define PASSIVE_REQUIRE_3D_IMAGE_SUPPORT( device ) \
|
||||
if( checkFor3DImageSupport( device ) ) \
|
||||
{ \
|
||||
log_info( "\n\tNote: device does not support 3D images. Skipping test...\n" ); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
/* Prints out the standard device header for all tests given the device to print for */
|
||||
extern int printDeviceHeader( cl_device_id device );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // _kernelHelpers_h
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _kernelHelpers_h
|
||||
#define _kernelHelpers_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined (__MINGW32__)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/opencl.h>
|
||||
#else
|
||||
#include <CL/opencl.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
/*
|
||||
* The below code is intended to be used at the top of kernels that appear inline in files to set line and file info for the kernel:
|
||||
*
|
||||
* const char *source = {
|
||||
* INIT_OPENCL_DEBUG_INFO
|
||||
* "__kernel void foo( int x )\n"
|
||||
* "{\n"
|
||||
* " ...\n"
|
||||
* "}\n"
|
||||
* };
|
||||
*/
|
||||
#define INIT_OPENCL_DEBUG_INFO SET_OPENCL_LINE_INFO( __LINE__, __FILE__ )
|
||||
#define SET_OPENCL_LINE_INFO(_line, _file) "#line " STRINGIFY(_line) " " STRINGIFY(_file) "\n"
|
||||
#ifndef STRINGIFY_VALUE
|
||||
#define STRINGIFY_VALUE(_x) STRINGIFY(_x)
|
||||
#endif
|
||||
#ifndef STRINGIFY
|
||||
#define STRINGIFY(_x) #_x
|
||||
#endif
|
||||
|
||||
/* Helper that creates a single program and kernel from a single-kernel program source */
|
||||
extern int create_single_kernel_helper( cl_context context, cl_program *outProgram, cl_kernel *outKernel, unsigned int numKernelLines, const char **kernelProgram, const char *kernelName );
|
||||
|
||||
/* Helper to obtain the biggest fit work group size for all the devices in a given group and for the given global thread size */
|
||||
extern int get_max_common_work_group_size( cl_context context, cl_kernel kernel, size_t globalThreadSize, size_t *outSize );
|
||||
|
||||
/* Helper to obtain the biggest fit work group size for all the devices in a given group and for the given global thread size */
|
||||
extern int get_max_common_2D_work_group_size( cl_context context, cl_kernel kernel, size_t *globalThreadSize, size_t *outSizes );
|
||||
|
||||
/* Helper to obtain the biggest fit work group size for all the devices in a given group and for the given global thread size */
|
||||
extern int get_max_common_3D_work_group_size( cl_context context, cl_kernel kernel, size_t *globalThreadSize, size_t *outSizes );
|
||||
|
||||
/* Helper to get major/minor number for a device */
|
||||
extern int get_device_version( cl_device_id id, size_t* major, size_t* minor);
|
||||
|
||||
/* Helper to obtain the biggest allowed work group size for all the devices in a given group */
|
||||
extern int get_max_allowed_work_group_size( cl_context context, cl_kernel kernel, size_t *outSize, size_t *outLimits );
|
||||
|
||||
/* Helper to determine if an extension is supported by a device */
|
||||
extern int is_extension_available( cl_device_id device, const char *extensionName );
|
||||
|
||||
/* Helper to determine if a device supports an image format */
|
||||
extern int is_image_format_supported( cl_context context, cl_mem_flags flags, cl_mem_object_type image_type, const cl_image_format *fmt );
|
||||
|
||||
/* Helper to get pixel size for a pixel format */
|
||||
size_t get_pixel_bytes( const cl_image_format *fmt );
|
||||
|
||||
/* Verify the given device supports images. 0 means you're good to go, otherwise an error */
|
||||
extern int verifyImageSupport( cl_device_id device );
|
||||
|
||||
/* Checks that the given device supports images. Same as verify, but doesn't print an error */
|
||||
extern int checkForImageSupport( cl_device_id device );
|
||||
extern int checkFor3DImageSupport( cl_device_id device );
|
||||
|
||||
/* Checks that a given queue property is supported on the specified device. Returns 1 if supported, 0 if not or an error. */
|
||||
extern int checkDeviceForQueueSupport( cl_device_id device, cl_command_queue_properties prop );
|
||||
|
||||
/* Helper for aligned memory allocation */
|
||||
void * align_malloc(size_t size, size_t alignment);
|
||||
void align_free(void *);
|
||||
|
||||
/* Helper to obtain the min alignment for a given context, i.e the max of all min alignments for devices attached to the context*/
|
||||
size_t get_min_alignment(cl_context context);
|
||||
|
||||
/* Helper to obtain the default rounding mode for single precision computation. (Double is always CL_FP_ROUND_TO_NEAREST.) Returns 0 on error. */
|
||||
cl_device_fp_config get_default_rounding_mode( cl_device_id device );
|
||||
|
||||
#define PASSIVE_REQUIRE_IMAGE_SUPPORT( device ) \
|
||||
if( checkForImageSupport( device ) ) \
|
||||
{ \
|
||||
log_info( "\n\tNote: device does not support images. Skipping test...\n" ); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define PASSIVE_REQUIRE_3D_IMAGE_SUPPORT( device ) \
|
||||
if( checkFor3DImageSupport( device ) ) \
|
||||
{ \
|
||||
log_info( "\n\tNote: device does not support 3D images. Skipping test...\n" ); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
/* Prints out the standard device header for all tests given the device to print for */
|
||||
extern int printDeviceHeader( cl_device_id device );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // _kernelHelpers_h
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#if defined(__MINGW32__)
|
||||
|
||||
#include "mingw_compat.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
//This function is unavailable on various mingw compilers,
|
||||
//especially 64 bit so implementing it here
|
||||
const char *basename_dot=".";
|
||||
char*
|
||||
basename(char *path)
|
||||
{
|
||||
char *p = path, *b = NULL;
|
||||
int len = strlen(path);
|
||||
|
||||
if (path == NULL) {
|
||||
return (char*)basename_dot;
|
||||
}
|
||||
|
||||
// Not absolute path on windows
|
||||
if (path[1] != ':') {
|
||||
return path;
|
||||
}
|
||||
|
||||
// Trim trailing path seperators
|
||||
if (path[len - 1] == '\\' ||
|
||||
path[len - 1] == '/' ) {
|
||||
len--;
|
||||
path[len] = '\0';
|
||||
}
|
||||
|
||||
while (len) {
|
||||
while((*p != '\\' || *p != '/') && len) {
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
p++;
|
||||
b = p;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#if defined(__MINGW32__)
|
||||
|
||||
#include "mingw_compat.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
//This function is unavailable on various mingw compilers,
|
||||
//especially 64 bit so implementing it here
|
||||
const char *basename_dot=".";
|
||||
char*
|
||||
basename(char *path)
|
||||
{
|
||||
char *p = path, *b = NULL;
|
||||
int len = strlen(path);
|
||||
|
||||
if (path == NULL) {
|
||||
return (char*)basename_dot;
|
||||
}
|
||||
|
||||
// Not absolute path on windows
|
||||
if (path[1] != ':') {
|
||||
return path;
|
||||
}
|
||||
|
||||
// Trim trailing path seperators
|
||||
if (path[len - 1] == '\\' ||
|
||||
path[len - 1] == '/' ) {
|
||||
len--;
|
||||
path[len] = '\0';
|
||||
}
|
||||
|
||||
while (len) {
|
||||
while((*p != '\\' || *p != '/') && len) {
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
p++;
|
||||
b = p;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,31 +1,31 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef MINGW_COMPAT_H
|
||||
#define MINGW_COMPAT_H
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
char *basename(char *path);
|
||||
#include <malloc.h>
|
||||
|
||||
#if defined(__MINGW64__)
|
||||
//mingw-w64 doesnot have __mingw_aligned_malloc, instead it has _aligned_malloc
|
||||
#define __mingw_aligned_malloc _aligned_malloc
|
||||
#define __mingw_aligned_free _aligned_free
|
||||
#include <stddef.h>
|
||||
#endif //(__MINGW64__)
|
||||
|
||||
#endif //(__MINGW32__)
|
||||
#endif // MINGW_COMPAT_H
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef MINGW_COMPAT_H
|
||||
#define MINGW_COMPAT_H
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
char *basename(char *path);
|
||||
#include <malloc.h>
|
||||
|
||||
#if defined(__MINGW64__)
|
||||
//mingw-w64 doesnot have __mingw_aligned_malloc, instead it has _aligned_malloc
|
||||
#define __mingw_aligned_malloc _aligned_malloc
|
||||
#define __mingw_aligned_free _aligned_free
|
||||
#include <stddef.h>
|
||||
#endif //(__MINGW64__)
|
||||
|
||||
#endif //(__MINGW32__)
|
||||
#endif // MINGW_COMPAT_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,274 +1,280 @@
|
||||
/*
|
||||
A C-program for MT19937, with initialization improved 2002/1/26.
|
||||
Coded by Takuji Nishimura and Makoto Matsumoto.
|
||||
|
||||
Before using, initialize the state by using init_genrand(seed)
|
||||
or init_by_array(init_key, key_length).
|
||||
|
||||
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The names of its contributors may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
Any feedback is very welcome.
|
||||
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
|
||||
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
|
||||
|
||||
Modifications for use in OpenCL by Ian Ollmann, Apple Inc.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "mt19937.h"
|
||||
#include "mingw_compat.h"
|
||||
|
||||
#ifdef __SSE2__
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
|
||||
static void * align_malloc(size_t size, size_t alignment)
|
||||
{
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
return _aligned_malloc(size, alignment);
|
||||
#elif defined(__linux__) || defined (linux) || defined(__APPLE__)
|
||||
void * ptr = NULL;
|
||||
if (0 == posix_memalign(&ptr, alignment, size))
|
||||
return ptr;
|
||||
return NULL;
|
||||
#elif defined(__MINGW32__)
|
||||
return __mingw_aligned_malloc(size, alignment);
|
||||
#else
|
||||
#error "Please add support OS for aligned malloc"
|
||||
#endif
|
||||
}
|
||||
|
||||
static void align_free(void * ptr)
|
||||
{
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
_aligned_free(ptr);
|
||||
#elif defined(__linux__) || defined (linux) || defined(__APPLE__)
|
||||
return free(ptr);
|
||||
#elif defined(__MINGW32__)
|
||||
return __mingw_aligned_free(ptr);
|
||||
#else
|
||||
#error "Please add support OS for aligned free"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Period parameters */
|
||||
#define N 624 /* vector code requires multiple of 4 here */
|
||||
#define M 397
|
||||
#define MATRIX_A (cl_uint) 0x9908b0dfUL /* constant vector a */
|
||||
#define UPPER_MASK (cl_uint) 0x80000000UL /* most significant w-r bits */
|
||||
#define LOWER_MASK (cl_uint) 0x7fffffffUL /* least significant r bits */
|
||||
|
||||
typedef struct _MTdata
|
||||
{
|
||||
cl_uint mt[N];
|
||||
#ifdef __SSE2__
|
||||
cl_uint cache[N];
|
||||
#endif
|
||||
cl_int mti;
|
||||
}_MTdata;
|
||||
|
||||
/* initializes mt[N] with a seed */
|
||||
MTdata init_genrand(cl_uint s)
|
||||
{
|
||||
MTdata r = (MTdata) align_malloc( sizeof( _MTdata ), 16 );
|
||||
if( NULL != r )
|
||||
{
|
||||
cl_uint *mt = r->mt;
|
||||
int mti = 0;
|
||||
mt[0]= s; // & 0xffffffffUL;
|
||||
for (mti=1; mti<N; mti++) {
|
||||
mt[mti] = (cl_uint)
|
||||
(1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
|
||||
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
|
||||
/* In the previous versions, MSBs of the seed affect */
|
||||
/* only MSBs of the array mt[]. */
|
||||
/* 2002/01/09 modified by Makoto Matsumoto */
|
||||
// mt[mti] &= 0xffffffffUL;
|
||||
/* for >32 bit machines */
|
||||
}
|
||||
r->mti = mti;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void free_mtdata( MTdata d )
|
||||
{
|
||||
if(d)
|
||||
align_free(d);
|
||||
}
|
||||
|
||||
/* generates a random number on [0,0xffffffff]-interval */
|
||||
cl_uint genrand_int32( MTdata d)
|
||||
{
|
||||
/* mag01[x] = x * MATRIX_A for x=0,1 */
|
||||
static const cl_uint mag01[2]={0x0UL, MATRIX_A};
|
||||
#ifdef __SSE2__
|
||||
static volatile int init = 0;
|
||||
static union{ __m128i v; cl_uint s[4]; } upper_mask, lower_mask, one, matrix_a, c0, c1;
|
||||
#endif
|
||||
|
||||
|
||||
cl_uint *mt = d->mt;
|
||||
cl_uint y;
|
||||
|
||||
if (d->mti == N)
|
||||
{ /* generate N words at one time */
|
||||
int kk;
|
||||
|
||||
#ifdef __SSE2__
|
||||
if( 0 == init )
|
||||
{
|
||||
upper_mask.s[0] = upper_mask.s[1] = upper_mask.s[2] = upper_mask.s[3] = UPPER_MASK;
|
||||
lower_mask.s[0] = lower_mask.s[1] = lower_mask.s[2] = lower_mask.s[3] = LOWER_MASK;
|
||||
one.s[0] = one.s[1] = one.s[2] = one.s[3] = 1;
|
||||
matrix_a.s[0] = matrix_a.s[1] = matrix_a.s[2] = matrix_a.s[3] = MATRIX_A;
|
||||
c0.s[0] = c0.s[1] = c0.s[2] = c0.s[3] = (cl_uint) 0x9d2c5680UL;
|
||||
c1.s[0] = c1.s[1] = c1.s[2] = c1.s[3] = (cl_uint) 0xefc60000UL;
|
||||
init = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
kk = 0;
|
||||
#ifdef __SSE2__
|
||||
// vector loop
|
||||
for( ; kk + 4 <= N-M; kk += 4 )
|
||||
{
|
||||
__m128i vy = _mm_or_si128( _mm_and_si128( _mm_load_si128( (__m128i*)(mt + kk) ), upper_mask.v ),
|
||||
_mm_and_si128( _mm_loadu_si128( (__m128i*)(mt + kk + 1) ), lower_mask.v )); // ((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK))
|
||||
|
||||
__m128i mask = _mm_cmpeq_epi32( _mm_and_si128( vy, one.v), one.v ); // y & 1 ? -1 : 0
|
||||
__m128i vmag01 = _mm_and_si128( mask, matrix_a.v ); // y & 1 ? MATRIX_A, 0 = mag01[y & (cl_uint) 0x1UL]
|
||||
__m128i vr = _mm_xor_si128( _mm_loadu_si128( (__m128i*)(mt + kk + M)), (__m128i) _mm_srli_epi32( vy, 1 ) ); // mt[kk+M] ^ (y >> 1)
|
||||
vr = _mm_xor_si128( vr, vmag01 ); // mt[kk+M] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL]
|
||||
_mm_store_si128( (__m128i*) (mt + kk ), vr );
|
||||
}
|
||||
#endif
|
||||
for ( ;kk<N-M;kk++) {
|
||||
y = (cl_uint) ((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK));
|
||||
mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL];
|
||||
}
|
||||
|
||||
#ifdef __SSE2__
|
||||
// advance to next aligned location
|
||||
for (;kk<N-1 && (kk & 3);kk++) {
|
||||
y = (cl_uint) ((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK));
|
||||
mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL];
|
||||
}
|
||||
|
||||
// vector loop
|
||||
for( ; kk + 4 <= N-1; kk += 4 )
|
||||
{
|
||||
__m128i vy = _mm_or_si128( _mm_and_si128( _mm_load_si128( (__m128i*)(mt + kk) ), upper_mask.v ),
|
||||
_mm_and_si128( _mm_loadu_si128( (__m128i*)(mt + kk + 1) ), lower_mask.v )); // ((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK))
|
||||
|
||||
__m128i mask = _mm_cmpeq_epi32( _mm_and_si128( vy, one.v), one.v ); // y & 1 ? -1 : 0
|
||||
__m128i vmag01 = _mm_and_si128( mask, matrix_a.v ); // y & 1 ? MATRIX_A, 0 = mag01[y & (cl_uint) 0x1UL]
|
||||
__m128i vr = _mm_xor_si128( _mm_loadu_si128( (__m128i*)(mt + kk + M - N)), _mm_srli_epi32( vy, 1 ) ); // mt[kk+M-N] ^ (y >> 1)
|
||||
vr = _mm_xor_si128( vr, vmag01 ); // mt[kk+M] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL]
|
||||
_mm_store_si128( (__m128i*) (mt + kk ), vr );
|
||||
}
|
||||
#endif
|
||||
|
||||
for (;kk<N-1;kk++) {
|
||||
y = (cl_uint) ((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK));
|
||||
mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL];
|
||||
}
|
||||
y = (cl_uint)((mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK));
|
||||
mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL];
|
||||
|
||||
#ifdef __SSE2__
|
||||
// Do the tempering ahead of time in vector code
|
||||
for( kk = 0; kk + 4 <= N; kk += 4 )
|
||||
{
|
||||
__m128i vy = _mm_load_si128( (__m128i*)(mt + kk ) ); // y = mt[k];
|
||||
vy = _mm_xor_si128( vy, _mm_srli_epi32( vy, 11 ) ); // y ^= (y >> 11);
|
||||
vy = _mm_xor_si128( vy, _mm_and_si128( _mm_slli_epi32( vy, 7 ), c0.v) ); // y ^= (y << 7) & (cl_uint) 0x9d2c5680UL;
|
||||
vy = _mm_xor_si128( vy, _mm_and_si128( _mm_slli_epi32( vy, 15 ), c1.v) ); // y ^= (y << 15) & (cl_uint) 0xefc60000UL;
|
||||
vy = _mm_xor_si128( vy, _mm_srli_epi32( vy, 18 ) ); // y ^= (y >> 18);
|
||||
_mm_store_si128( (__m128i*)(d->cache+kk), vy );
|
||||
}
|
||||
#endif
|
||||
|
||||
d->mti = 0;
|
||||
}
|
||||
#ifdef __SSE2__
|
||||
y = d->cache[d->mti++];
|
||||
#else
|
||||
y = mt[d->mti++];
|
||||
|
||||
/* Tempering */
|
||||
y ^= (y >> 11);
|
||||
y ^= (y << 7) & (cl_uint) 0x9d2c5680UL;
|
||||
y ^= (y << 15) & (cl_uint) 0xefc60000UL;
|
||||
y ^= (y >> 18);
|
||||
#endif
|
||||
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
cl_ulong genrand_int64( MTdata d)
|
||||
{
|
||||
return ((cl_ulong) genrand_int32(d) << 32) | (cl_uint) genrand_int32(d);
|
||||
}
|
||||
|
||||
/* generates a random number on [0,1]-real-interval */
|
||||
double genrand_real1(MTdata d)
|
||||
{
|
||||
return genrand_int32(d)*(1.0/4294967295.0);
|
||||
/* divided by 2^32-1 */
|
||||
}
|
||||
|
||||
/* generates a random number on [0,1)-real-interval */
|
||||
double genrand_real2(MTdata d)
|
||||
{
|
||||
return genrand_int32(d)*(1.0/4294967296.0);
|
||||
/* divided by 2^32 */
|
||||
}
|
||||
|
||||
/* generates a random number on (0,1)-real-interval */
|
||||
double genrand_real3(MTdata d)
|
||||
{
|
||||
return (((double)genrand_int32(d)) + 0.5)*(1.0/4294967296.0);
|
||||
/* divided by 2^32 */
|
||||
}
|
||||
|
||||
/* generates a random number on [0,1) with 53-bit resolution*/
|
||||
double genrand_res53(MTdata d)
|
||||
{
|
||||
unsigned long a=genrand_int32(d)>>5, b=genrand_int32(d)>>6;
|
||||
return(a*67108864.0+b)*(1.0/9007199254740992.0);
|
||||
}
|
||||
/*
|
||||
A C-program for MT19937, with initialization improved 2002/1/26.
|
||||
Coded by Takuji Nishimura and Makoto Matsumoto.
|
||||
|
||||
Before using, initialize the state by using init_genrand(seed)
|
||||
or init_by_array(init_key, key_length).
|
||||
|
||||
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The names of its contributors may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
Any feedback is very welcome.
|
||||
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
|
||||
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
|
||||
|
||||
Modifications for use in OpenCL by Ian Ollmann, Apple Inc.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "mt19937.h"
|
||||
#include "mingw_compat.h"
|
||||
|
||||
#ifdef __SSE2__
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
|
||||
static void * align_malloc(size_t size, size_t alignment)
|
||||
{
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
return _aligned_malloc(size, alignment);
|
||||
#elif defined(__linux__) || defined (linux) || defined(__APPLE__)
|
||||
void * ptr = NULL;
|
||||
#if defined(__ANDROID__)
|
||||
ptr = memalign(alignment, size);
|
||||
if ( ptr )
|
||||
return ptr;
|
||||
#else
|
||||
if (0 == posix_memalign(&ptr, alignment, size))
|
||||
return ptr;
|
||||
#endif
|
||||
return NULL;
|
||||
#elif defined(__MINGW32__)
|
||||
return __mingw_aligned_malloc(size, alignment);
|
||||
#else
|
||||
#error "Please add support OS for aligned malloc"
|
||||
#endif
|
||||
}
|
||||
|
||||
static void align_free(void * ptr)
|
||||
{
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
_aligned_free(ptr);
|
||||
#elif defined(__linux__) || defined (linux) || defined(__APPLE__)
|
||||
return free(ptr);
|
||||
#elif defined(__MINGW32__)
|
||||
return __mingw_aligned_free(ptr);
|
||||
#else
|
||||
#error "Please add support OS for aligned free"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Period parameters */
|
||||
#define N 624 /* vector code requires multiple of 4 here */
|
||||
#define M 397
|
||||
#define MATRIX_A (cl_uint) 0x9908b0dfUL /* constant vector a */
|
||||
#define UPPER_MASK (cl_uint) 0x80000000UL /* most significant w-r bits */
|
||||
#define LOWER_MASK (cl_uint) 0x7fffffffUL /* least significant r bits */
|
||||
|
||||
typedef struct _MTdata
|
||||
{
|
||||
cl_uint mt[N];
|
||||
#ifdef __SSE2__
|
||||
cl_uint cache[N];
|
||||
#endif
|
||||
cl_int mti;
|
||||
}_MTdata;
|
||||
|
||||
/* initializes mt[N] with a seed */
|
||||
MTdata init_genrand(cl_uint s)
|
||||
{
|
||||
MTdata r = (MTdata) align_malloc( sizeof( _MTdata ), 16 );
|
||||
if( NULL != r )
|
||||
{
|
||||
cl_uint *mt = r->mt;
|
||||
int mti = 0;
|
||||
mt[0]= s; // & 0xffffffffUL;
|
||||
for (mti=1; mti<N; mti++) {
|
||||
mt[mti] = (cl_uint)
|
||||
(1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
|
||||
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
|
||||
/* In the previous versions, MSBs of the seed affect */
|
||||
/* only MSBs of the array mt[]. */
|
||||
/* 2002/01/09 modified by Makoto Matsumoto */
|
||||
// mt[mti] &= 0xffffffffUL;
|
||||
/* for >32 bit machines */
|
||||
}
|
||||
r->mti = mti;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void free_mtdata( MTdata d )
|
||||
{
|
||||
if(d)
|
||||
align_free(d);
|
||||
}
|
||||
|
||||
/* generates a random number on [0,0xffffffff]-interval */
|
||||
cl_uint genrand_int32( MTdata d)
|
||||
{
|
||||
/* mag01[x] = x * MATRIX_A for x=0,1 */
|
||||
static const cl_uint mag01[2]={0x0UL, MATRIX_A};
|
||||
#ifdef __SSE2__
|
||||
static volatile int init = 0;
|
||||
static union{ __m128i v; cl_uint s[4]; } upper_mask, lower_mask, one, matrix_a, c0, c1;
|
||||
#endif
|
||||
|
||||
|
||||
cl_uint *mt = d->mt;
|
||||
cl_uint y;
|
||||
|
||||
if (d->mti == N)
|
||||
{ /* generate N words at one time */
|
||||
int kk;
|
||||
|
||||
#ifdef __SSE2__
|
||||
if( 0 == init )
|
||||
{
|
||||
upper_mask.s[0] = upper_mask.s[1] = upper_mask.s[2] = upper_mask.s[3] = UPPER_MASK;
|
||||
lower_mask.s[0] = lower_mask.s[1] = lower_mask.s[2] = lower_mask.s[3] = LOWER_MASK;
|
||||
one.s[0] = one.s[1] = one.s[2] = one.s[3] = 1;
|
||||
matrix_a.s[0] = matrix_a.s[1] = matrix_a.s[2] = matrix_a.s[3] = MATRIX_A;
|
||||
c0.s[0] = c0.s[1] = c0.s[2] = c0.s[3] = (cl_uint) 0x9d2c5680UL;
|
||||
c1.s[0] = c1.s[1] = c1.s[2] = c1.s[3] = (cl_uint) 0xefc60000UL;
|
||||
init = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
kk = 0;
|
||||
#ifdef __SSE2__
|
||||
// vector loop
|
||||
for( ; kk + 4 <= N-M; kk += 4 )
|
||||
{
|
||||
__m128i vy = _mm_or_si128( _mm_and_si128( _mm_load_si128( (__m128i*)(mt + kk) ), upper_mask.v ),
|
||||
_mm_and_si128( _mm_loadu_si128( (__m128i*)(mt + kk + 1) ), lower_mask.v )); // ((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK))
|
||||
|
||||
__m128i mask = _mm_cmpeq_epi32( _mm_and_si128( vy, one.v), one.v ); // y & 1 ? -1 : 0
|
||||
__m128i vmag01 = _mm_and_si128( mask, matrix_a.v ); // y & 1 ? MATRIX_A, 0 = mag01[y & (cl_uint) 0x1UL]
|
||||
__m128i vr = _mm_xor_si128( _mm_loadu_si128( (__m128i*)(mt + kk + M)), (__m128i) _mm_srli_epi32( vy, 1 ) ); // mt[kk+M] ^ (y >> 1)
|
||||
vr = _mm_xor_si128( vr, vmag01 ); // mt[kk+M] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL]
|
||||
_mm_store_si128( (__m128i*) (mt + kk ), vr );
|
||||
}
|
||||
#endif
|
||||
for ( ;kk<N-M;kk++) {
|
||||
y = (cl_uint) ((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK));
|
||||
mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL];
|
||||
}
|
||||
|
||||
#ifdef __SSE2__
|
||||
// advance to next aligned location
|
||||
for (;kk<N-1 && (kk & 3);kk++) {
|
||||
y = (cl_uint) ((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK));
|
||||
mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL];
|
||||
}
|
||||
|
||||
// vector loop
|
||||
for( ; kk + 4 <= N-1; kk += 4 )
|
||||
{
|
||||
__m128i vy = _mm_or_si128( _mm_and_si128( _mm_load_si128( (__m128i*)(mt + kk) ), upper_mask.v ),
|
||||
_mm_and_si128( _mm_loadu_si128( (__m128i*)(mt + kk + 1) ), lower_mask.v )); // ((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK))
|
||||
|
||||
__m128i mask = _mm_cmpeq_epi32( _mm_and_si128( vy, one.v), one.v ); // y & 1 ? -1 : 0
|
||||
__m128i vmag01 = _mm_and_si128( mask, matrix_a.v ); // y & 1 ? MATRIX_A, 0 = mag01[y & (cl_uint) 0x1UL]
|
||||
__m128i vr = _mm_xor_si128( _mm_loadu_si128( (__m128i*)(mt + kk + M - N)), _mm_srli_epi32( vy, 1 ) ); // mt[kk+M-N] ^ (y >> 1)
|
||||
vr = _mm_xor_si128( vr, vmag01 ); // mt[kk+M] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL]
|
||||
_mm_store_si128( (__m128i*) (mt + kk ), vr );
|
||||
}
|
||||
#endif
|
||||
|
||||
for (;kk<N-1;kk++) {
|
||||
y = (cl_uint) ((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK));
|
||||
mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL];
|
||||
}
|
||||
y = (cl_uint)((mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK));
|
||||
mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL];
|
||||
|
||||
#ifdef __SSE2__
|
||||
// Do the tempering ahead of time in vector code
|
||||
for( kk = 0; kk + 4 <= N; kk += 4 )
|
||||
{
|
||||
__m128i vy = _mm_load_si128( (__m128i*)(mt + kk ) ); // y = mt[k];
|
||||
vy = _mm_xor_si128( vy, _mm_srli_epi32( vy, 11 ) ); // y ^= (y >> 11);
|
||||
vy = _mm_xor_si128( vy, _mm_and_si128( _mm_slli_epi32( vy, 7 ), c0.v) ); // y ^= (y << 7) & (cl_uint) 0x9d2c5680UL;
|
||||
vy = _mm_xor_si128( vy, _mm_and_si128( _mm_slli_epi32( vy, 15 ), c1.v) ); // y ^= (y << 15) & (cl_uint) 0xefc60000UL;
|
||||
vy = _mm_xor_si128( vy, _mm_srli_epi32( vy, 18 ) ); // y ^= (y >> 18);
|
||||
_mm_store_si128( (__m128i*)(d->cache+kk), vy );
|
||||
}
|
||||
#endif
|
||||
|
||||
d->mti = 0;
|
||||
}
|
||||
#ifdef __SSE2__
|
||||
y = d->cache[d->mti++];
|
||||
#else
|
||||
y = mt[d->mti++];
|
||||
|
||||
/* Tempering */
|
||||
y ^= (y >> 11);
|
||||
y ^= (y << 7) & (cl_uint) 0x9d2c5680UL;
|
||||
y ^= (y << 15) & (cl_uint) 0xefc60000UL;
|
||||
y ^= (y >> 18);
|
||||
#endif
|
||||
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
cl_ulong genrand_int64( MTdata d)
|
||||
{
|
||||
return ((cl_ulong) genrand_int32(d) << 32) | (cl_uint) genrand_int32(d);
|
||||
}
|
||||
|
||||
/* generates a random number on [0,1]-real-interval */
|
||||
double genrand_real1(MTdata d)
|
||||
{
|
||||
return genrand_int32(d)*(1.0/4294967295.0);
|
||||
/* divided by 2^32-1 */
|
||||
}
|
||||
|
||||
/* generates a random number on [0,1)-real-interval */
|
||||
double genrand_real2(MTdata d)
|
||||
{
|
||||
return genrand_int32(d)*(1.0/4294967296.0);
|
||||
/* divided by 2^32 */
|
||||
}
|
||||
|
||||
/* generates a random number on (0,1)-real-interval */
|
||||
double genrand_real3(MTdata d)
|
||||
{
|
||||
return (((double)genrand_int32(d)) + 0.5)*(1.0/4294967296.0);
|
||||
/* divided by 2^32 */
|
||||
}
|
||||
|
||||
/* generates a random number on [0,1) with 53-bit resolution*/
|
||||
double genrand_res53(MTdata d)
|
||||
{
|
||||
unsigned long a=genrand_int32(d)>>5, b=genrand_int32(d)>>6;
|
||||
return(a*67108864.0+b)*(1.0/9007199254740992.0);
|
||||
}
|
||||
|
||||
@@ -1,99 +1,99 @@
|
||||
|
||||
/*
|
||||
* mt19937.h
|
||||
*
|
||||
* Mersenne Twister.
|
||||
*
|
||||
A C-program for MT19937, with initialization improved 2002/1/26.
|
||||
Coded by Takuji Nishimura and Makoto Matsumoto.
|
||||
|
||||
Before using, initialize the state by using init_genrand(seed)
|
||||
or init_by_array(init_key, key_length).
|
||||
|
||||
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The names of its contributors may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
Any feedback is very welcome.
|
||||
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
|
||||
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
|
||||
*/
|
||||
|
||||
#ifndef MT19937_H
|
||||
#define MT19937_H 1
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenCL/cl_platform.h>
|
||||
#else
|
||||
#include <CL/cl_platform.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Interfaces here have been modified from original sources so that they
|
||||
* are safe to call reentrantly, so long as a different MTdata is used
|
||||
* on each thread.
|
||||
*/
|
||||
|
||||
typedef struct _MTdata *MTdata;
|
||||
|
||||
/* Create the random number generator with seed */
|
||||
MTdata init_genrand( cl_uint /*seed*/ );
|
||||
|
||||
/* release memory used by a MTdata private data */
|
||||
void free_mtdata( MTdata /*data*/ );
|
||||
|
||||
/* generates a random number on [0,0xffffffff]-interval */
|
||||
cl_uint genrand_int32( MTdata /*data*/);
|
||||
|
||||
/* generates a random number on [0,0xffffffffffffffffULL]-interval */
|
||||
cl_ulong genrand_int64( MTdata /*data*/);
|
||||
|
||||
/* generates a random number on [0,1]-real-interval */
|
||||
double genrand_real1( MTdata /*data*/);
|
||||
|
||||
/* generates a random number on [0,1)-real-interval */
|
||||
double genrand_real2( MTdata /*data*/);
|
||||
|
||||
/* generates a random number on (0,1)-real-interval */
|
||||
double genrand_real3( MTdata /*data*/);
|
||||
|
||||
/* generates a random number on [0,1) with 53-bit resolution*/
|
||||
double genrand_res53( MTdata /*data*/ );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MT19937_H */
|
||||
|
||||
/*
|
||||
* mt19937.h
|
||||
*
|
||||
* Mersenne Twister.
|
||||
*
|
||||
A C-program for MT19937, with initialization improved 2002/1/26.
|
||||
Coded by Takuji Nishimura and Makoto Matsumoto.
|
||||
|
||||
Before using, initialize the state by using init_genrand(seed)
|
||||
or init_by_array(init_key, key_length).
|
||||
|
||||
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The names of its contributors may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
Any feedback is very welcome.
|
||||
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
|
||||
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
|
||||
*/
|
||||
|
||||
#ifndef MT19937_H
|
||||
#define MT19937_H 1
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#include <OpenCL/cl_platform.h>
|
||||
#else
|
||||
#include <CL/cl_platform.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Interfaces here have been modified from original sources so that they
|
||||
* are safe to call reentrantly, so long as a different MTdata is used
|
||||
* on each thread.
|
||||
*/
|
||||
|
||||
typedef struct _MTdata *MTdata;
|
||||
|
||||
/* Create the random number generator with seed */
|
||||
MTdata init_genrand( cl_uint /*seed*/ );
|
||||
|
||||
/* release memory used by a MTdata private data */
|
||||
void free_mtdata( MTdata /*data*/ );
|
||||
|
||||
/* generates a random number on [0,0xffffffff]-interval */
|
||||
cl_uint genrand_int32( MTdata /*data*/);
|
||||
|
||||
/* generates a random number on [0,0xffffffffffffffffULL]-interval */
|
||||
cl_ulong genrand_int64( MTdata /*data*/);
|
||||
|
||||
/* generates a random number on [0,1]-real-interval */
|
||||
double genrand_real1( MTdata /*data*/);
|
||||
|
||||
/* generates a random number on [0,1)-real-interval */
|
||||
double genrand_real2( MTdata /*data*/);
|
||||
|
||||
/* generates a random number on (0,1)-real-interval */
|
||||
double genrand_real3( MTdata /*data*/);
|
||||
|
||||
/* generates a random number on [0,1) with 53-bit resolution*/
|
||||
double genrand_res53( MTdata /*data*/ );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MT19937_H */
|
||||
|
||||
564
test_common/harness/os_helpers.cpp
Normal file
564
test_common/harness/os_helpers.cpp
Normal file
@@ -0,0 +1,564 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "os_helpers.h"
|
||||
#include "errorHelpers.h"
|
||||
|
||||
// =================================================================================================
|
||||
// C++ interface.
|
||||
// =================================================================================================
|
||||
|
||||
#include <cerrno> // errno, error constants
|
||||
#include <climits> // PATH_MAX
|
||||
#include <cstdlib> // abort, _splitpath, _makepath
|
||||
#include <cstring> // strdup, strerror_r
|
||||
#include <sstream>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#define CHECK_PTR( ptr ) \
|
||||
if ( (ptr) == NULL ) { \
|
||||
abort(); \
|
||||
}
|
||||
|
||||
typedef std::vector< char > buffer_t;
|
||||
|
||||
#if ! defined( PATH_MAX )
|
||||
#define PATH_MAX 1000
|
||||
#endif
|
||||
|
||||
int const _size = PATH_MAX + 1; // Initial buffer size for path.
|
||||
int const _count = 8; // How many times we will try to double buffer size.
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// MacOS X
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
|
||||
|
||||
#include <mach-o/dyld.h> // _NSGetExecutablePath
|
||||
#include <libgen.h> // dirname
|
||||
|
||||
|
||||
static
|
||||
std::string
|
||||
_err_msg(
|
||||
int err, // Error number (e. g. errno).
|
||||
int level // Nesting level, for avoiding infinite recursion.
|
||||
) {
|
||||
|
||||
/*
|
||||
There are 3 incompatible versions of strerror_r:
|
||||
|
||||
char * strerror_r( int, char *, size_t ); // GNU version
|
||||
int strerror_r( int, char *, size_t ); // BSD version
|
||||
int strerror_r( int, char *, size_t ); // XSI version
|
||||
|
||||
BSD version returns error code, while XSI version returns 0 or -1 and sets errno.
|
||||
|
||||
*/
|
||||
|
||||
// BSD version of strerror_r.
|
||||
buffer_t buffer( 100 );
|
||||
int count = _count;
|
||||
for ( ; ; ) {
|
||||
int rc = strerror_r( err, & buffer.front(), buffer.size() );
|
||||
if ( rc == EINVAL ) {
|
||||
// Error code is not recognized, but anyway we got the message.
|
||||
return & buffer.front();
|
||||
} else if ( rc == ERANGE ) {
|
||||
// Buffer is not enough.
|
||||
if ( count > 0 ) {
|
||||
// Enlarge the buffer.
|
||||
-- count;
|
||||
buffer.resize( buffer.size() * 2 );
|
||||
} else {
|
||||
std::stringstream ostr;
|
||||
ostr
|
||||
<< "Error " << err << " "
|
||||
<< "(Getting error message failed: "
|
||||
<< "Buffer of " << buffer.size() << " bytes is still too small"
|
||||
<< ")";
|
||||
return ostr.str();
|
||||
}; // if
|
||||
} else if ( rc == 0 ) {
|
||||
// We got the message.
|
||||
return & buffer.front();
|
||||
} else {
|
||||
std::stringstream ostr;
|
||||
ostr
|
||||
<< "Error " << err << " "
|
||||
<< "(Getting error message failed: "
|
||||
<< ( level < 2 ? _err_msg( rc, level + 1 ) : "Oops" )
|
||||
<< ")";
|
||||
return ostr.str();
|
||||
}; // if
|
||||
}; // forever
|
||||
|
||||
} // _err_msg
|
||||
|
||||
|
||||
std::string
|
||||
dir_sep(
|
||||
) {
|
||||
return "/";
|
||||
} // dir_sep
|
||||
|
||||
|
||||
std::string
|
||||
exe_path(
|
||||
) {
|
||||
buffer_t path( _size );
|
||||
int count = _count;
|
||||
for ( ; ; ) {
|
||||
uint32_t size = path.size();
|
||||
int rc = _NSGetExecutablePath( & path.front(), & size );
|
||||
if ( rc == 0 ) {
|
||||
break;
|
||||
}; // if
|
||||
if ( count > 0 ) {
|
||||
-- count;
|
||||
path.resize( size );
|
||||
} else {
|
||||
log_error(
|
||||
"ERROR: Getting executable path failed: "
|
||||
"_NSGetExecutablePath failed: Buffer of %lu bytes is still too small\n",
|
||||
(unsigned long) path.size()
|
||||
);
|
||||
exit( 2 );
|
||||
}; // if
|
||||
}; // forever
|
||||
return & path.front();
|
||||
} // exe_path
|
||||
|
||||
|
||||
std::string
|
||||
exe_dir(
|
||||
) {
|
||||
std::string path = exe_path();
|
||||
// We cannot pass path.c_str() to `dirname' bacause `dirname' modifies its argument.
|
||||
buffer_t buffer( path.c_str(), path.c_str() + path.size() + 1 ); // Copy with trailing zero.
|
||||
return dirname( & buffer.front() );
|
||||
} // exe_dir
|
||||
|
||||
|
||||
#endif // __APPLE__
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// Linux
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
#if defined( __linux__ )
|
||||
|
||||
|
||||
#include <cerrno> // errno
|
||||
#include <libgen.h> // dirname
|
||||
#include <unistd.h> // readlink
|
||||
|
||||
|
||||
static
|
||||
std::string
|
||||
_err_msg(
|
||||
int err,
|
||||
int level
|
||||
) {
|
||||
|
||||
/*
|
||||
There are 3 incompatible versions of strerror_r:
|
||||
|
||||
char * strerror_r( int, char *, size_t ); // GNU version
|
||||
int strerror_r( int, char *, size_t ); // BSD version
|
||||
int strerror_r( int, char *, size_t ); // XSI version
|
||||
|
||||
BSD version returns error code, while XSI version returns 0 or -1 and sets errno.
|
||||
|
||||
*/
|
||||
|
||||
#if defined(__ANDROID__) || ( ( _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 ) && ! _GNU_SOURCE )
|
||||
|
||||
// XSI version of strerror_r.
|
||||
#warning Not tested!
|
||||
buffer_t buffer( 200 );
|
||||
int count = _count;
|
||||
for ( ; ; ) {
|
||||
int rc = strerror_r( err, & buffer.front(), buffer.size() );
|
||||
if ( rc == -1 ) {
|
||||
int _err = errno;
|
||||
if ( _err == ERANGE ) {
|
||||
if ( count > 0 ) {
|
||||
// Enlarge the buffer.
|
||||
-- count;
|
||||
buffer.resize( buffer.size() * 2 );
|
||||
} else {
|
||||
std::stringstream ostr;
|
||||
ostr
|
||||
<< "Error " << err << " "
|
||||
<< "(Getting error message failed: "
|
||||
<< "Buffer of " << buffer.size() << " bytes is still too small"
|
||||
<< ")";
|
||||
return ostr.str();
|
||||
}; // if
|
||||
} else {
|
||||
std::stringstream ostr;
|
||||
ostr
|
||||
<< "Error " << err << " "
|
||||
<< "(Getting error message failed: "
|
||||
<< ( level < 2 ? _err_msg( _err, level + 1 ) : "Oops" )
|
||||
<< ")";
|
||||
return ostr.str();
|
||||
}; // if
|
||||
} else {
|
||||
// We got the message.
|
||||
return & buffer.front();
|
||||
}; // if
|
||||
}; // forever
|
||||
|
||||
#else
|
||||
|
||||
// GNU version of strerror_r.
|
||||
char buffer[ 2000 ];
|
||||
return strerror_r( err, buffer, sizeof( buffer ) );
|
||||
|
||||
#endif
|
||||
|
||||
} // _err_msg
|
||||
|
||||
|
||||
std::string
|
||||
dir_sep(
|
||||
) {
|
||||
return "/";
|
||||
} // dir_sep
|
||||
|
||||
|
||||
std::string
|
||||
exe_path(
|
||||
) {
|
||||
|
||||
static std::string const exe = "/proc/self/exe";
|
||||
|
||||
buffer_t path( _size );
|
||||
int count = _count; // Max number of iterations.
|
||||
|
||||
for ( ; ; ) {
|
||||
|
||||
ssize_t len = readlink( exe.c_str(), & path.front(), path.size() );
|
||||
|
||||
if ( len < 0 ) {
|
||||
// Oops.
|
||||
int err = errno;
|
||||
log_error(
|
||||
"ERROR: Getting executable path failed: "
|
||||
"Reading symlink `%s' failed: %s\n",
|
||||
exe.c_str(), err_msg( err ).c_str()
|
||||
);
|
||||
exit( 2 );
|
||||
}; // if
|
||||
|
||||
if ( len < path.size() ) {
|
||||
// We got the path.
|
||||
path.resize( len );
|
||||
break;
|
||||
}; // if
|
||||
|
||||
// Oops, buffer is too small.
|
||||
if ( count > 0 ) {
|
||||
-- count;
|
||||
// Enlarge the buffer.
|
||||
path.resize( path.size() * 2 );
|
||||
} else {
|
||||
log_error(
|
||||
"ERROR: Getting executable path failed: "
|
||||
"Reading symlink `%s' failed: Buffer of %lu bytes is still too small\n",
|
||||
exe.c_str(),
|
||||
(unsigned long) path.size()
|
||||
);
|
||||
exit( 2 );
|
||||
}; // if
|
||||
|
||||
}; // forever
|
||||
|
||||
return std::string( & path.front(), path.size() );
|
||||
|
||||
} // exe_path
|
||||
|
||||
|
||||
std::string
|
||||
exe_dir(
|
||||
) {
|
||||
std::string path = exe_path();
|
||||
// We cannot pass path.c_str() to `dirname' bacause `dirname' modifies its argument.
|
||||
buffer_t buffer( path.c_str(), path.c_str() + path.size() + 1 ); // Copy with trailing zero.
|
||||
return dirname( & buffer.front() );
|
||||
} // exe_dir
|
||||
|
||||
#endif // __linux__
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// MS Windows
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
#if defined( _WIN32 )
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#if defined( max )
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
#include <cctype>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
static
|
||||
std::string
|
||||
_err_msg(
|
||||
int err,
|
||||
int level
|
||||
) {
|
||||
|
||||
std::string msg;
|
||||
|
||||
LPSTR buffer = NULL;
|
||||
DWORD flags =
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS;
|
||||
|
||||
DWORD len =
|
||||
FormatMessageA(
|
||||
flags,
|
||||
NULL,
|
||||
err,
|
||||
LANG_USER_DEFAULT,
|
||||
reinterpret_cast< LPSTR >( & buffer ),
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
|
||||
if ( buffer == NULL || len == 0 ) {
|
||||
|
||||
int _err = GetLastError();
|
||||
char str[1024] = { 0 };
|
||||
snprintf(str, sizeof(str), "Error 0x%08x (Getting error message failed: %s )", err, ( level < 2 ? _err_msg( _err, level + 1 ).c_str() : "Oops" ));
|
||||
msg = std::string(str);
|
||||
|
||||
} else {
|
||||
|
||||
// Trim trailing whitespace (including `\r' and `\n').
|
||||
while ( len > 0 && isspace( buffer[ len - 1 ] ) ) {
|
||||
-- len;
|
||||
}; // while
|
||||
|
||||
// Drop trailing full stop.
|
||||
if ( len > 0 && buffer[ len - 1 ] == '.' ) {
|
||||
-- len;
|
||||
}; // if
|
||||
|
||||
msg.assign( buffer, len );
|
||||
|
||||
}; //if
|
||||
|
||||
if ( buffer != NULL ) {
|
||||
LocalFree( buffer );
|
||||
}; // if
|
||||
|
||||
return msg;
|
||||
|
||||
} // _get_err_msg
|
||||
|
||||
|
||||
std::string
|
||||
dir_sep(
|
||||
) {
|
||||
return "\\";
|
||||
} // dir_sep
|
||||
|
||||
|
||||
std::string
|
||||
exe_path(
|
||||
) {
|
||||
|
||||
buffer_t path( _size );
|
||||
int count = _count;
|
||||
|
||||
for ( ; ; ) {
|
||||
|
||||
DWORD len = GetModuleFileNameA( NULL, & path.front(), path.size() );
|
||||
|
||||
if ( len == 0 ) {
|
||||
int err = GetLastError();
|
||||
log_error( "ERROR: Getting executable path failed: %s\n", err_msg( err ).c_str() );
|
||||
exit( 2 );
|
||||
}; // if
|
||||
|
||||
if ( len < path.size() ) {
|
||||
path.resize( len );
|
||||
break;
|
||||
}; // if
|
||||
|
||||
// Buffer too small.
|
||||
if ( count > 0 ) {
|
||||
-- count;
|
||||
path.resize( path.size() * 2 );
|
||||
} else {
|
||||
log_error(
|
||||
"ERROR: Getting executable path failed: "
|
||||
"Buffer of %lu bytes is still too small\n",
|
||||
(unsigned long) path.size()
|
||||
);
|
||||
exit( 2 );
|
||||
}; // if
|
||||
|
||||
}; // forever
|
||||
|
||||
return std::string( & path.front(), path.size() );
|
||||
|
||||
} // exe_path
|
||||
|
||||
|
||||
std::string
|
||||
exe_dir(
|
||||
) {
|
||||
|
||||
std::string exe = exe_path();
|
||||
int count = 0;
|
||||
|
||||
// Splitting path into components.
|
||||
buffer_t drv( _MAX_DRIVE );
|
||||
buffer_t dir( _MAX_DIR );
|
||||
count = _count;
|
||||
#if defined(_MSC_VER)
|
||||
for ( ; ; ) {
|
||||
int rc =
|
||||
_splitpath_s(
|
||||
exe.c_str(),
|
||||
& drv.front(), drv.size(),
|
||||
& dir.front(), dir.size(),
|
||||
NULL, 0, // We need neither name
|
||||
NULL, 0 // nor extension
|
||||
);
|
||||
if ( rc == 0 ) {
|
||||
break;
|
||||
} else if ( rc == ERANGE ) {
|
||||
if ( count > 0 ) {
|
||||
-- count;
|
||||
// Buffer is too small, but it is not clear which one.
|
||||
// So we have to enlarge all.
|
||||
drv.resize( drv.size() * 2 );
|
||||
dir.resize( dir.size() * 2 );
|
||||
} else {
|
||||
log_error(
|
||||
"ERROR: Getting executable path failed: "
|
||||
"Splitting path `%s' to components failed: "
|
||||
"Buffers of %lu and %lu bytes are still too small\n",
|
||||
exe.c_str(),
|
||||
(unsigned long) drv.size(),
|
||||
(unsigned long) dir.size()
|
||||
);
|
||||
exit( 2 );
|
||||
}; // if
|
||||
} else {
|
||||
log_error(
|
||||
"ERROR: Getting executable path failed: "
|
||||
"Splitting path `%s' to components failed: %s\n",
|
||||
exe.c_str(),
|
||||
err_msg( rc ).c_str()
|
||||
);
|
||||
exit( 2 );
|
||||
}; // if
|
||||
}; // forever
|
||||
|
||||
#else // __MINGW32__
|
||||
|
||||
// MinGW does not have the "secure" _splitpath_s, use the insecure version instead.
|
||||
_splitpath(
|
||||
exe.c_str(),
|
||||
& drv.front(),
|
||||
& dir.front(),
|
||||
NULL, // We need neither name
|
||||
NULL // nor extension
|
||||
);
|
||||
#endif // __MINGW32__
|
||||
|
||||
// Combining components back to path.
|
||||
// I failed with "secure" `_makepath_s'. If buffer is too small, instead of returning
|
||||
// ERANGE, `_makepath_s' pops up dialog box and offers to debug the program. D'oh!
|
||||
// So let us try to guess the size of result and go with insecure `_makepath'.
|
||||
buffer_t path( std::max( drv.size() + dir.size(), size_t( _MAX_PATH ) ) + 10 );
|
||||
_makepath( & path.front(), & drv.front(), & dir.front(), NULL, NULL );
|
||||
|
||||
return & path.front();
|
||||
|
||||
} // exe_dir
|
||||
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
|
||||
std::string
|
||||
err_msg(
|
||||
int err
|
||||
) {
|
||||
|
||||
return _err_msg( err, 0 );
|
||||
|
||||
} // err_msg
|
||||
|
||||
|
||||
// =================================================================================================
|
||||
// C interface.
|
||||
// =================================================================================================
|
||||
|
||||
|
||||
char *
|
||||
get_err_msg(
|
||||
int err
|
||||
) {
|
||||
char * msg = strdup( err_msg( err ).c_str() );
|
||||
CHECK_PTR( msg );
|
||||
return msg;
|
||||
} // get_err_msg
|
||||
|
||||
|
||||
char *
|
||||
get_dir_sep(
|
||||
) {
|
||||
char * sep = strdup( dir_sep().c_str() );
|
||||
CHECK_PTR( sep );
|
||||
return sep;
|
||||
} // get_dir_sep
|
||||
|
||||
|
||||
char *
|
||||
get_exe_path(
|
||||
) {
|
||||
char * path = strdup( exe_path().c_str() );
|
||||
CHECK_PTR( path );
|
||||
return path;
|
||||
} // get_exe_path
|
||||
|
||||
|
||||
char *
|
||||
get_exe_dir(
|
||||
) {
|
||||
char * dir = strdup( exe_dir().c_str() );
|
||||
CHECK_PTR( dir );
|
||||
return dir;
|
||||
} // get_exe_dir
|
||||
|
||||
|
||||
// end of file //
|
||||
53
test_common/harness/os_helpers.h
Normal file
53
test_common/harness/os_helpers.h
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef __os_helpers_h__
|
||||
#define __os_helpers_h__
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// C++ interface.
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string err_msg( int err );
|
||||
std::string dir_sep();
|
||||
std::string exe_path();
|
||||
std::string exe_dir();
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// C interface.
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
char * get_err_msg( int err ); // Returns system error message. Subject to free.
|
||||
char * get_dir_sep(); // Returns dir separator. Subject to free.
|
||||
char * get_exe_path(); // Returns path of current executable. Subject to free.
|
||||
char * get_exe_dir(); // Returns dir of current executable. Subject to free.
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __os_helpers_h__
|
||||
42
test_common/harness/parseParameters.cpp
Normal file
42
test_common/harness/parseParameters.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "parseParameters.h"
|
||||
#include "errorHelpers.h"
|
||||
#include <string.h>
|
||||
|
||||
bool is_power_of_two(int number)
|
||||
{
|
||||
return number && !(number & (number - 1));
|
||||
}
|
||||
|
||||
extern void parseWimpyReductionFactor(const char *&arg, int &wimpyReductionFactor)
|
||||
{
|
||||
const char *arg_temp = strchr(&arg[1], ']');
|
||||
if (arg_temp != 0)
|
||||
{
|
||||
int new_factor = atoi(&arg[1]);
|
||||
arg = arg_temp; // Advance until ']'
|
||||
if (is_power_of_two(new_factor))
|
||||
{
|
||||
log_info("\n Wimpy reduction factor changed from %d to %d \n", wimpyReductionFactor, new_factor);
|
||||
wimpyReductionFactor = new_factor;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_info("\n WARNING: Incorrect wimpy reduction factor %d, must be power of 2. The default value will be used.\n", new_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
24
test_common/harness/parseParameters.h
Normal file
24
test_common/harness/parseParameters.h
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _parseParameters_h
|
||||
#define _parseParameters_h
|
||||
|
||||
#include "compat.h"
|
||||
#include <string>
|
||||
|
||||
extern void parseWimpyReductionFactor(const char *&arg, int &wimpyReductionFactor);
|
||||
|
||||
#endif // _parseParameters_h
|
||||
@@ -1,49 +1,49 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _ref_counting_h
|
||||
#define _ref_counting_h
|
||||
|
||||
#define MARK_REF_COUNT_BASE( c, type, bigType ) \
|
||||
cl_uint c##_refCount; \
|
||||
error = clGet##type##Info( c, CL_##bigType##_REFERENCE_COUNT, sizeof( c##_refCount ), &c##_refCount, NULL ); \
|
||||
test_error( error, "Unable to check reference count for " #type );
|
||||
|
||||
#define TEST_REF_COUNT_BASE( c, type, bigType ) \
|
||||
cl_uint c##_refCount_new; \
|
||||
error = clGet##type##Info( c, CL_##bigType##_REFERENCE_COUNT, sizeof( c##_refCount_new ), &c##_refCount_new, NULL ); \
|
||||
test_error( error, "Unable to check reference count for " #type ); \
|
||||
if( c##_refCount != c##_refCount_new ) \
|
||||
{ \
|
||||
log_error( "ERROR: Reference count for " #type " changed! (was %d, now %d)\n", c##_refCount, c##_refCount_new ); \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
#define MARK_REF_COUNT_CONTEXT( c ) MARK_REF_COUNT_BASE( c, Context, CONTEXT )
|
||||
#define TEST_REF_COUNT_CONTEXT( c ) TEST_REF_COUNT_BASE( c, Context, CONTEXT )
|
||||
|
||||
#define MARK_REF_COUNT_DEVICE( c ) MARK_REF_COUNT_BASE( c, Device, DEVICE )
|
||||
#define TEST_REF_COUNT_DEVICE( c ) TEST_REF_COUNT_BASE( c, Device, DEVICE )
|
||||
|
||||
#define MARK_REF_COUNT_QUEUE( c ) MARK_REF_COUNT_BASE( c, CommandQueue, QUEUE )
|
||||
#define TEST_REF_COUNT_QUEUE( c ) TEST_REF_COUNT_BASE( c, CommandQueue, QUEUE )
|
||||
|
||||
#define MARK_REF_COUNT_PROGRAM( c ) MARK_REF_COUNT_BASE( c, Program, PROGRAM )
|
||||
#define TEST_REF_COUNT_PROGRAM( c ) TEST_REF_COUNT_BASE( c, Program, PROGRAM )
|
||||
|
||||
#define MARK_REF_COUNT_MEM( c ) MARK_REF_COUNT_BASE( c, MemObject, MEM )
|
||||
#define TEST_REF_COUNT_MEM( c ) TEST_REF_COUNT_BASE( c, MemObject, MEM )
|
||||
|
||||
#endif // _ref_counting_h
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _ref_counting_h
|
||||
#define _ref_counting_h
|
||||
|
||||
#define MARK_REF_COUNT_BASE( c, type, bigType ) \
|
||||
cl_uint c##_refCount; \
|
||||
error = clGet##type##Info( c, CL_##bigType##_REFERENCE_COUNT, sizeof( c##_refCount ), &c##_refCount, NULL ); \
|
||||
test_error( error, "Unable to check reference count for " #type );
|
||||
|
||||
#define TEST_REF_COUNT_BASE( c, type, bigType ) \
|
||||
cl_uint c##_refCount_new; \
|
||||
error = clGet##type##Info( c, CL_##bigType##_REFERENCE_COUNT, sizeof( c##_refCount_new ), &c##_refCount_new, NULL ); \
|
||||
test_error( error, "Unable to check reference count for " #type ); \
|
||||
if( c##_refCount != c##_refCount_new ) \
|
||||
{ \
|
||||
log_error( "ERROR: Reference count for " #type " changed! (was %d, now %d)\n", c##_refCount, c##_refCount_new ); \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
#define MARK_REF_COUNT_CONTEXT( c ) MARK_REF_COUNT_BASE( c, Context, CONTEXT )
|
||||
#define TEST_REF_COUNT_CONTEXT( c ) TEST_REF_COUNT_BASE( c, Context, CONTEXT )
|
||||
|
||||
#define MARK_REF_COUNT_DEVICE( c ) MARK_REF_COUNT_BASE( c, Device, DEVICE )
|
||||
#define TEST_REF_COUNT_DEVICE( c ) TEST_REF_COUNT_BASE( c, Device, DEVICE )
|
||||
|
||||
#define MARK_REF_COUNT_QUEUE( c ) MARK_REF_COUNT_BASE( c, CommandQueue, QUEUE )
|
||||
#define TEST_REF_COUNT_QUEUE( c ) TEST_REF_COUNT_BASE( c, CommandQueue, QUEUE )
|
||||
|
||||
#define MARK_REF_COUNT_PROGRAM( c ) MARK_REF_COUNT_BASE( c, Program, PROGRAM )
|
||||
#define TEST_REF_COUNT_PROGRAM( c ) TEST_REF_COUNT_BASE( c, Program, PROGRAM )
|
||||
|
||||
#define MARK_REF_COUNT_MEM( c ) MARK_REF_COUNT_BASE( c, MemObject, MEM )
|
||||
#define TEST_REF_COUNT_MEM( c ) TEST_REF_COUNT_BASE( c, MemObject, MEM )
|
||||
|
||||
#endif // _ref_counting_h
|
||||
|
||||
@@ -1,175 +1,241 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "rounding_mode.h"
|
||||
|
||||
#if !(defined(_WIN32) && defined(_MSC_VER))
|
||||
RoundingMode set_round( RoundingMode r, Type outType )
|
||||
{
|
||||
static const int flt_rounds[ kRoundingModeCount ] = { FE_TONEAREST, FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO };
|
||||
static const int int_rounds[ kRoundingModeCount ] = { FE_TOWARDZERO, FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO };
|
||||
const int *p = int_rounds;
|
||||
if( outType == kfloat || outType == kdouble )
|
||||
p = flt_rounds;
|
||||
int oldRound = fegetround();
|
||||
fesetround( p[r] );
|
||||
|
||||
switch( oldRound )
|
||||
{
|
||||
case FE_TONEAREST:
|
||||
return kRoundToNearestEven;
|
||||
case FE_UPWARD:
|
||||
return kRoundUp;
|
||||
case FE_DOWNWARD:
|
||||
return kRoundDown;
|
||||
case FE_TOWARDZERO:
|
||||
return kRoundTowardZero;
|
||||
default:
|
||||
abort(); // ??!
|
||||
}
|
||||
return kDefaultRoundingMode; //never happens
|
||||
}
|
||||
|
||||
RoundingMode get_round( void )
|
||||
{
|
||||
int oldRound = fegetround();
|
||||
|
||||
switch( oldRound )
|
||||
{
|
||||
case FE_TONEAREST:
|
||||
return kRoundToNearestEven;
|
||||
case FE_UPWARD:
|
||||
return kRoundUp;
|
||||
case FE_DOWNWARD:
|
||||
return kRoundDown;
|
||||
case FE_TOWARDZERO:
|
||||
return kRoundTowardZero;
|
||||
}
|
||||
|
||||
return kDefaultRoundingMode;
|
||||
}
|
||||
|
||||
#else
|
||||
RoundingMode set_round( RoundingMode r, Type outType )
|
||||
{
|
||||
static const int flt_rounds[ kRoundingModeCount ] = { _RC_NEAR, _RC_NEAR, _RC_UP, _RC_DOWN, _RC_CHOP };
|
||||
static const int int_rounds[ kRoundingModeCount ] = { _RC_CHOP, _RC_NEAR, _RC_UP, _RC_DOWN, _RC_CHOP };
|
||||
const int *p = ( outType == kfloat || outType == kdouble )? flt_rounds : int_rounds;
|
||||
unsigned int oldRound;
|
||||
|
||||
int err = _controlfp_s(&oldRound, 0, 0); //get rounding mode into oldRound
|
||||
if (err) {
|
||||
vlog_error("\t\tERROR: -- cannot get rounding mode in %s:%d\n", __FILE__, __LINE__);
|
||||
return kDefaultRoundingMode; //what else never happens
|
||||
}
|
||||
|
||||
oldRound &= _MCW_RC;
|
||||
|
||||
RoundingMode old =
|
||||
(oldRound == _RC_NEAR)? kRoundToNearestEven :
|
||||
(oldRound == _RC_UP)? kRoundUp :
|
||||
(oldRound == _RC_DOWN)? kRoundDown :
|
||||
(oldRound == _RC_CHOP)? kRoundTowardZero:
|
||||
kDefaultRoundingMode;
|
||||
|
||||
_controlfp_s(&oldRound, p[r], _MCW_RC); //setting new rounding mode
|
||||
return old; //returning old rounding mode
|
||||
}
|
||||
|
||||
RoundingMode get_round( void )
|
||||
{
|
||||
unsigned int oldRound;
|
||||
|
||||
int err = _controlfp_s(&oldRound, 0, 0); //get rounding mode into oldRound
|
||||
oldRound &= _MCW_RC;
|
||||
return
|
||||
(oldRound == _RC_NEAR)? kRoundToNearestEven :
|
||||
(oldRound == _RC_UP)? kRoundUp :
|
||||
(oldRound == _RC_DOWN)? kRoundDown :
|
||||
(oldRound == _RC_CHOP)? kRoundTowardZero:
|
||||
kDefaultRoundingMode;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// FlushToZero() sets the host processor into ftz mode. It is intended to have a remote effect on the behavior of the code in
|
||||
// basic_test_conversions.c. Some host processors may not support this mode, which case you'll need to do some clamping in
|
||||
// software by testing against FLT_MIN or DBL_MIN in that file.
|
||||
//
|
||||
// Note: IEEE-754 says conversions are basic operations. As such they do *NOT* have the behavior in section 7.5.3 of
|
||||
// the OpenCL spec. They *ALWAYS* flush to zero for subnormal inputs or outputs when FTZ mode is on like other basic
|
||||
// operators do (e.g. add, subtract, multiply, divide, etc.)
|
||||
//
|
||||
// Configuring hardware to FTZ mode varies by platform.
|
||||
// CAUTION: Some C implementations may also fail to behave properly in this mode.
|
||||
//
|
||||
// On PowerPC, it is done by setting the FPSCR into non-IEEE mode.
|
||||
// On Intel, you can do this by turning on the FZ and DAZ bits in the MXCSR -- provided that SSE/SSE2
|
||||
// is used for floating point computation! If your OS uses x87, you'll need to figure out how
|
||||
// to turn that off for the conversions code in basic_test_conversions.c so that they flush to
|
||||
// zero properly. Otherwise, you'll need to add appropriate software clamping to basic_test_conversions.c
|
||||
// in which case, these function are at liberty to do nothing.
|
||||
//
|
||||
#if defined( __i386__ ) || defined( __x86_64__ ) || defined (_WIN32)
|
||||
#include <xmmintrin.h>
|
||||
#elif defined( __PPC__ )
|
||||
#include <fpu_control.h>
|
||||
#endif
|
||||
void *FlushToZero( void )
|
||||
{
|
||||
#if defined( __APPLE__ ) || defined(__linux__) || defined (_WIN32)
|
||||
#if defined( __i386__ ) || defined( __x86_64__ ) || defined(_MSC_VER)
|
||||
union{ int i; void *p; }u = { _mm_getcsr() };
|
||||
_mm_setcsr( u.i | 0x8040 );
|
||||
return u.p;
|
||||
#elif defined( __arm__ )
|
||||
// processor is already in FTZ mode -- do nothing
|
||||
return NULL;
|
||||
#elif defined( __PPC__ )
|
||||
fpu_control_t flags = 0;
|
||||
_FPU_GETCW(flags);
|
||||
flags |= _FPU_MASK_NI;
|
||||
_FPU_SETCW(flags);
|
||||
return NULL;
|
||||
#else
|
||||
#error Unknown arch
|
||||
#endif
|
||||
#else
|
||||
#error Please configure FlushToZero and UnFlushToZero to behave properly on this operating system.
|
||||
#endif
|
||||
}
|
||||
|
||||
// Undo the effects of FlushToZero above, restoring the host to default behavior, using the information passed in p.
|
||||
void UnFlushToZero( void *p)
|
||||
{
|
||||
#if defined( __APPLE__ ) || defined(__linux__) || defined (_WIN32)
|
||||
#if defined( __i386__ ) || defined( __x86_64__ ) || defined(_MSC_VER)
|
||||
union{ void *p; int i; }u = { p };
|
||||
_mm_setcsr( u.i );
|
||||
#elif defined( __arm__ )
|
||||
// processor is already in FTZ mode -- do nothing
|
||||
#elif defined( __PPC__)
|
||||
fpu_control_t flags = 0;
|
||||
_FPU_GETCW(flags);
|
||||
flags &= ~_FPU_MASK_NI;
|
||||
_FPU_SETCW(flags);
|
||||
#else
|
||||
#error Unknown arch
|
||||
#endif
|
||||
#else
|
||||
#error Please configure FlushToZero and UnFlushToZero to behave properly on this operating system.
|
||||
#endif
|
||||
}
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "rounding_mode.h"
|
||||
|
||||
#if (defined( __arm__ ) || defined(__aarch64__))
|
||||
#define FPSCR_FZ (1 << 24) // Flush-To-Zero mode
|
||||
#define FPSCR_ROUND_MASK (3 << 22) // Rounding mode:
|
||||
|
||||
#define _ARM_FE_FTZ 0x1000000
|
||||
#define _ARM_FE_NFTZ 0x0
|
||||
#if defined(__aarch64__)
|
||||
#define _FPU_GETCW(cw) __asm__ ("MRS %0,FPCR" : "=r" (cw))
|
||||
#define _FPU_SETCW(cw) __asm__ ("MSR FPCR,%0" : :"ri" (cw))
|
||||
#else
|
||||
#define _FPU_GETCW(cw) __asm__ ("VMRS %0,FPSCR" : "=r" (cw))
|
||||
#define _FPU_SETCW(cw) __asm__ ("VMSR FPSCR,%0" : :"ri" (cw))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined( __arm__ ) || defined(__aarch64__)) && defined( __GNUC__ )
|
||||
#define _ARM_FE_TONEAREST 0x0
|
||||
#define _ARM_FE_UPWARD 0x400000
|
||||
#define _ARM_FE_DOWNWARD 0x800000
|
||||
#define _ARM_FE_TOWARDZERO 0xc00000
|
||||
RoundingMode set_round( RoundingMode r, Type outType )
|
||||
{
|
||||
static const int flt_rounds[ kRoundingModeCount ] = { _ARM_FE_TONEAREST,
|
||||
_ARM_FE_TONEAREST, _ARM_FE_UPWARD, _ARM_FE_DOWNWARD, _ARM_FE_TOWARDZERO };
|
||||
static const int int_rounds[ kRoundingModeCount ] = { _ARM_FE_TOWARDZERO,
|
||||
_ARM_FE_TONEAREST, _ARM_FE_UPWARD, _ARM_FE_DOWNWARD, _ARM_FE_TOWARDZERO };
|
||||
const int *p = int_rounds;
|
||||
if( outType == kfloat || outType == kdouble )
|
||||
p = flt_rounds;
|
||||
|
||||
int fpscr = 0;
|
||||
RoundingMode oldRound = get_round();
|
||||
|
||||
_FPU_GETCW(fpscr);
|
||||
_FPU_SETCW( p[r] | (fpscr & ~FPSCR_ROUND_MASK));
|
||||
|
||||
return oldRound;
|
||||
}
|
||||
|
||||
RoundingMode get_round( void )
|
||||
{
|
||||
int fpscr;
|
||||
int oldRound;
|
||||
|
||||
_FPU_GETCW(fpscr);
|
||||
oldRound = (fpscr & FPSCR_ROUND_MASK);
|
||||
|
||||
switch( oldRound )
|
||||
{
|
||||
case _ARM_FE_TONEAREST:
|
||||
return kRoundToNearestEven;
|
||||
case _ARM_FE_UPWARD:
|
||||
return kRoundUp;
|
||||
case _ARM_FE_DOWNWARD:
|
||||
return kRoundDown;
|
||||
case _ARM_FE_TOWARDZERO:
|
||||
return kRoundTowardZero;
|
||||
}
|
||||
|
||||
return kDefaultRoundingMode;
|
||||
}
|
||||
|
||||
#elif !(defined(_WIN32) && defined(_MSC_VER))
|
||||
RoundingMode set_round( RoundingMode r, Type outType )
|
||||
{
|
||||
static const int flt_rounds[ kRoundingModeCount ] = { FE_TONEAREST, FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO };
|
||||
static const int int_rounds[ kRoundingModeCount ] = { FE_TOWARDZERO, FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO };
|
||||
const int *p = int_rounds;
|
||||
if( outType == kfloat || outType == kdouble )
|
||||
p = flt_rounds;
|
||||
int oldRound = fegetround();
|
||||
fesetround( p[r] );
|
||||
|
||||
switch( oldRound )
|
||||
{
|
||||
case FE_TONEAREST:
|
||||
return kRoundToNearestEven;
|
||||
case FE_UPWARD:
|
||||
return kRoundUp;
|
||||
case FE_DOWNWARD:
|
||||
return kRoundDown;
|
||||
case FE_TOWARDZERO:
|
||||
return kRoundTowardZero;
|
||||
default:
|
||||
abort(); // ??!
|
||||
}
|
||||
return kDefaultRoundingMode; //never happens
|
||||
}
|
||||
|
||||
RoundingMode get_round( void )
|
||||
{
|
||||
int oldRound = fegetround();
|
||||
|
||||
switch( oldRound )
|
||||
{
|
||||
case FE_TONEAREST:
|
||||
return kRoundToNearestEven;
|
||||
case FE_UPWARD:
|
||||
return kRoundUp;
|
||||
case FE_DOWNWARD:
|
||||
return kRoundDown;
|
||||
case FE_TOWARDZERO:
|
||||
return kRoundTowardZero;
|
||||
}
|
||||
|
||||
return kDefaultRoundingMode;
|
||||
}
|
||||
|
||||
#else
|
||||
RoundingMode set_round( RoundingMode r, Type outType )
|
||||
{
|
||||
static const int flt_rounds[ kRoundingModeCount ] = { _RC_NEAR, _RC_NEAR, _RC_UP, _RC_DOWN, _RC_CHOP };
|
||||
static const int int_rounds[ kRoundingModeCount ] = { _RC_CHOP, _RC_NEAR, _RC_UP, _RC_DOWN, _RC_CHOP };
|
||||
const int *p = ( outType == kfloat || outType == kdouble )? flt_rounds : int_rounds;
|
||||
unsigned int oldRound;
|
||||
|
||||
int err = _controlfp_s(&oldRound, 0, 0); //get rounding mode into oldRound
|
||||
if (err) {
|
||||
vlog_error("\t\tERROR: -- cannot get rounding mode in %s:%d\n", __FILE__, __LINE__);
|
||||
return kDefaultRoundingMode; //what else never happens
|
||||
}
|
||||
|
||||
oldRound &= _MCW_RC;
|
||||
|
||||
RoundingMode old =
|
||||
(oldRound == _RC_NEAR)? kRoundToNearestEven :
|
||||
(oldRound == _RC_UP)? kRoundUp :
|
||||
(oldRound == _RC_DOWN)? kRoundDown :
|
||||
(oldRound == _RC_CHOP)? kRoundTowardZero:
|
||||
kDefaultRoundingMode;
|
||||
|
||||
_controlfp_s(&oldRound, p[r], _MCW_RC); //setting new rounding mode
|
||||
return old; //returning old rounding mode
|
||||
}
|
||||
|
||||
RoundingMode get_round( void )
|
||||
{
|
||||
unsigned int oldRound;
|
||||
|
||||
int err = _controlfp_s(&oldRound, 0, 0); //get rounding mode into oldRound
|
||||
oldRound &= _MCW_RC;
|
||||
return
|
||||
(oldRound == _RC_NEAR)? kRoundToNearestEven :
|
||||
(oldRound == _RC_UP)? kRoundUp :
|
||||
(oldRound == _RC_DOWN)? kRoundDown :
|
||||
(oldRound == _RC_CHOP)? kRoundTowardZero:
|
||||
kDefaultRoundingMode;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// FlushToZero() sets the host processor into ftz mode. It is intended to have a remote effect on the behavior of the code in
|
||||
// basic_test_conversions.c. Some host processors may not support this mode, which case you'll need to do some clamping in
|
||||
// software by testing against FLT_MIN or DBL_MIN in that file.
|
||||
//
|
||||
// Note: IEEE-754 says conversions are basic operations. As such they do *NOT* have the behavior in section 7.5.3 of
|
||||
// the OpenCL spec. They *ALWAYS* flush to zero for subnormal inputs or outputs when FTZ mode is on like other basic
|
||||
// operators do (e.g. add, subtract, multiply, divide, etc.)
|
||||
//
|
||||
// Configuring hardware to FTZ mode varies by platform.
|
||||
// CAUTION: Some C implementations may also fail to behave properly in this mode.
|
||||
//
|
||||
// On PowerPC, it is done by setting the FPSCR into non-IEEE mode.
|
||||
// On Intel, you can do this by turning on the FZ and DAZ bits in the MXCSR -- provided that SSE/SSE2
|
||||
// is used for floating point computation! If your OS uses x87, you'll need to figure out how
|
||||
// to turn that off for the conversions code in basic_test_conversions.c so that they flush to
|
||||
// zero properly. Otherwise, you'll need to add appropriate software clamping to basic_test_conversions.c
|
||||
// in which case, these function are at liberty to do nothing.
|
||||
//
|
||||
#if defined( __i386__ ) || defined( __x86_64__ ) || defined (_WIN32)
|
||||
#include <xmmintrin.h>
|
||||
#elif defined( __PPC__ )
|
||||
#include <fpu_control.h>
|
||||
#endif
|
||||
void *FlushToZero( void )
|
||||
{
|
||||
#if defined( __APPLE__ ) || defined(__linux__) || defined (_WIN32)
|
||||
#if defined( __i386__ ) || defined( __x86_64__ ) || defined(_MSC_VER)
|
||||
union{ int i; void *p; }u = { _mm_getcsr() };
|
||||
_mm_setcsr( u.i | 0x8040 );
|
||||
return u.p;
|
||||
#elif defined( __arm__ ) || defined(__aarch64__)
|
||||
int fpscr;
|
||||
_FPU_GETCW(fpscr);
|
||||
_FPU_SETCW(fpscr | FPSCR_FZ);
|
||||
return NULL;
|
||||
#elif defined( __PPC__ )
|
||||
fpu_control_t flags = 0;
|
||||
_FPU_GETCW(flags);
|
||||
flags |= _FPU_MASK_NI;
|
||||
_FPU_SETCW(flags);
|
||||
return NULL;
|
||||
#else
|
||||
#error Unknown arch
|
||||
#endif
|
||||
#else
|
||||
#error Please configure FlushToZero and UnFlushToZero to behave properly on this operating system.
|
||||
#endif
|
||||
}
|
||||
|
||||
// Undo the effects of FlushToZero above, restoring the host to default behavior, using the information passed in p.
|
||||
void UnFlushToZero( void *p)
|
||||
{
|
||||
#if defined( __APPLE__ ) || defined(__linux__) || defined (_WIN32)
|
||||
#if defined( __i386__ ) || defined( __x86_64__ ) || defined(_MSC_VER)
|
||||
union{ void *p; int i; }u = { p };
|
||||
_mm_setcsr( u.i );
|
||||
#elif defined( __arm__ ) || defined(__aarch64__)
|
||||
int fpscr;
|
||||
_FPU_GETCW(fpscr);
|
||||
_FPU_SETCW(fpscr & ~FPSCR_FZ);
|
||||
#elif defined( __PPC__)
|
||||
fpu_control_t flags = 0;
|
||||
_FPU_GETCW(flags);
|
||||
flags &= ~_FPU_MASK_NI;
|
||||
_FPU_SETCW(flags);
|
||||
#else
|
||||
#error Unknown arch
|
||||
#endif
|
||||
#else
|
||||
#error Please configure FlushToZero and UnFlushToZero to behave properly on this operating system.
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,73 +1,69 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef __ROUNDING_MODE_H__
|
||||
#define __ROUNDING_MODE_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if (defined(_WIN32) && defined (_MSC_VER))
|
||||
// need for _controlfp_s and rouinding modes in RoundingMode
|
||||
#include <float.h>
|
||||
#include "errorHelpers.h"
|
||||
#include "testHarness.h"
|
||||
#else
|
||||
#include <fenv.h>
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
kDefaultRoundingMode = 0,
|
||||
kRoundToNearestEven,
|
||||
kRoundUp,
|
||||
kRoundDown,
|
||||
kRoundTowardZero,
|
||||
|
||||
kRoundingModeCount
|
||||
}RoundingMode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
kuchar = 0,
|
||||
kchar = 1,
|
||||
kushort = 2,
|
||||
kshort = 3,
|
||||
kuint = 4,
|
||||
kint = 5,
|
||||
kfloat = 6,
|
||||
kdouble = 7,
|
||||
kulong = 8,
|
||||
klong = 9,
|
||||
|
||||
//This goes last
|
||||
kTypeCount
|
||||
}Type;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern RoundingMode set_round( RoundingMode r, Type outType );
|
||||
extern RoundingMode get_round( void );
|
||||
extern void *FlushToZero( void );
|
||||
extern void UnFlushToZero( void *p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /* __ROUNDING_MODE_H__ */
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef __ROUNDING_MODE_H__
|
||||
#define __ROUNDING_MODE_H__
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#if (defined(_WIN32) && defined (_MSC_VER))
|
||||
#include "errorHelpers.h"
|
||||
#include "testHarness.h"
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
kDefaultRoundingMode = 0,
|
||||
kRoundToNearestEven,
|
||||
kRoundUp,
|
||||
kRoundDown,
|
||||
kRoundTowardZero,
|
||||
|
||||
kRoundingModeCount
|
||||
}RoundingMode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
kuchar = 0,
|
||||
kchar = 1,
|
||||
kushort = 2,
|
||||
kshort = 3,
|
||||
kuint = 4,
|
||||
kint = 5,
|
||||
kfloat = 6,
|
||||
kdouble = 7,
|
||||
kulong = 8,
|
||||
klong = 9,
|
||||
|
||||
//This goes last
|
||||
kTypeCount
|
||||
}Type;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern RoundingMode set_round( RoundingMode r, Type outType );
|
||||
extern RoundingMode get_round( void );
|
||||
extern void *FlushToZero( void );
|
||||
extern void UnFlushToZero( void *p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /* __ROUNDING_MODE_H__ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,104 +1,104 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _testHarness_h
|
||||
#define _testHarness_h
|
||||
|
||||
#include "threadTesting.h"
|
||||
#include "clImageHelper.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern cl_uint gReSeed;
|
||||
extern cl_uint gRandomSeed;
|
||||
|
||||
// Supply a list of functions to test here. This will allocate a CL device, create a context, all that
|
||||
// setup work, and then call each function in turn as dictatated by the passed arguments.
|
||||
extern int runTestHarness( int argc, const char *argv[], unsigned int num_fns,
|
||||
basefn fnList[], const char *fnNames[],
|
||||
int imageSupportRequired, int forceNoContextCreation, cl_command_queue_properties queueProps );
|
||||
|
||||
// Device checking function. See runTestHarnessWithCheck. If this function returns anything other than CL_SUCCESS (0), the harness exits.
|
||||
typedef int (*DeviceCheckFn)( cl_device_id device );
|
||||
|
||||
// Same as runTestHarness, but also supplies a function that checks the created device for required functionality.
|
||||
extern int runTestHarnessWithCheck( int argc, const char *argv[], unsigned int num_fns,
|
||||
basefn fnList[], const char *fnNames[],
|
||||
int imageSupportRequired, int forceNoContextCreation, cl_command_queue_properties queueProps, DeviceCheckFn deviceCheckFn );
|
||||
|
||||
// The command line parser used by runTestHarness to break up parameters into calls to callTestFunctions
|
||||
extern int parseAndCallCommandLineTests( int argc, const char *argv[], cl_device_id device, unsigned int num_fns,
|
||||
basefn *fnList, const char *fnNames[],
|
||||
int forceNoContextCreation, cl_command_queue_properties queueProps, int num_elements );
|
||||
|
||||
// Call this function if you need to do all the setup work yourself, and just need the function list called/
|
||||
// managed.
|
||||
// functionIndexToCall can be a valid index into the function list, or -1 to run all of them.
|
||||
// partialName can be a string to partially match function names against and only execute functions who
|
||||
// match, or NULL to not restrict execution (ignored if functionIndexToCall is not -1)
|
||||
// functionList is the actual array of functions
|
||||
// numFunctions is the number of functions in the list (which should NOT have NULL at the end for "all")
|
||||
// functionNames is an array of strings representing the name of each function, to be used in partial matching
|
||||
// contextProps are used to create a testing context for each test
|
||||
// deviceToUse, deviceGroupToUse and numElementsToUse are all just passed to each test function
|
||||
|
||||
extern int callTestFunctions( basefn functionList[], int numFunctions,
|
||||
const char *functionNames[],
|
||||
cl_device_id deviceToUse, int forceNoContextCreation,
|
||||
int numElementsToUse,
|
||||
int functionIndexToCall, const char *partialName, cl_command_queue_properties queueProps );
|
||||
|
||||
// This function is called by callTestFunctions, once per function, to do setup, call, logging and cleanup
|
||||
extern int callSingleTestFunction( basefn functionToCall, const char *functionName,
|
||||
cl_device_id deviceToUse, int forceNoContextCreation,
|
||||
int numElementsToUse, cl_command_queue_properties queueProps );
|
||||
|
||||
///// Miscellaneous steps
|
||||
|
||||
// Given a pre-existing device type choice, check the environment for an override, then print what
|
||||
// choice was made and how (and return the overridden choice, if there is one)
|
||||
extern void checkDeviceTypeOverride( cl_device_type *inOutType );
|
||||
|
||||
// standard callback function for context pfn_notify
|
||||
extern void CL_CALLBACK notify_callback(const char *errinfo, const void *private_info, size_t cb, void *user_data);
|
||||
|
||||
extern cl_device_type GetDeviceType( cl_device_id );
|
||||
|
||||
// Given a device (most likely passed in by the harness, but not required), will attempt to find
|
||||
// a DIFFERENT device and return it. Useful for finding another device to run multi-device tests against.
|
||||
// Note that returning NULL means an error was hit, but if no error was hit and the device passed in
|
||||
// is the only device available, the SAME device is returned, so check!
|
||||
extern cl_device_id GetOpposingDevice( cl_device_id device );
|
||||
|
||||
|
||||
extern int gFlushDenormsToZero; // This is set to 1 if the device does not support denorms (CL_FP_DENORM)
|
||||
extern int gInfNanSupport; // This is set to 1 if the device supports infinities and NaNs
|
||||
extern int gIsEmbedded; // This is set to 1 if the device is an embedded device
|
||||
extern int gHasLong; // This is set to 1 if the device suppots long and ulong types in OpenCL C.
|
||||
extern int gIsOpenCL_C_1_0_Device; // This is set to 1 if the device supports only OpenCL C 1.0.
|
||||
|
||||
#if ! defined( __APPLE__ )
|
||||
void memset_pattern4(void *, const void *, size_t);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _testHarness_h
|
||||
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _testHarness_h
|
||||
#define _testHarness_h
|
||||
|
||||
#include "threadTesting.h"
|
||||
#include "clImageHelper.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern cl_uint gReSeed;
|
||||
extern cl_uint gRandomSeed;
|
||||
|
||||
// Supply a list of functions to test here. This will allocate a CL device, create a context, all that
|
||||
// setup work, and then call each function in turn as dictatated by the passed arguments.
|
||||
extern int runTestHarness( int argc, const char *argv[], unsigned int num_fns,
|
||||
basefn fnList[], const char *fnNames[],
|
||||
int imageSupportRequired, int forceNoContextCreation, cl_command_queue_properties queueProps );
|
||||
|
||||
// Device checking function. See runTestHarnessWithCheck. If this function returns anything other than CL_SUCCESS (0), the harness exits.
|
||||
typedef int (*DeviceCheckFn)( cl_device_id device );
|
||||
|
||||
// Same as runTestHarness, but also supplies a function that checks the created device for required functionality.
|
||||
extern int runTestHarnessWithCheck( int argc, const char *argv[], unsigned int num_fns,
|
||||
basefn fnList[], const char *fnNames[],
|
||||
int imageSupportRequired, int forceNoContextCreation, cl_command_queue_properties queueProps, DeviceCheckFn deviceCheckFn );
|
||||
|
||||
// The command line parser used by runTestHarness to break up parameters into calls to callTestFunctions
|
||||
extern int parseAndCallCommandLineTests( int argc, const char *argv[], cl_device_id device, unsigned int num_fns,
|
||||
basefn *fnList, const char *fnNames[],
|
||||
int forceNoContextCreation, cl_command_queue_properties queueProps, int num_elements );
|
||||
|
||||
// Call this function if you need to do all the setup work yourself, and just need the function list called/
|
||||
// managed.
|
||||
// functionIndexToCall can be a valid index into the function list, or -1 to run all of them.
|
||||
// partialName can be a string to partially match function names against and only execute functions who
|
||||
// match, or NULL to not restrict execution (ignored if functionIndexToCall is not -1)
|
||||
// functionList is the actual array of functions
|
||||
// numFunctions is the number of functions in the list (which should NOT have NULL at the end for "all")
|
||||
// functionNames is an array of strings representing the name of each function, to be used in partial matching
|
||||
// contextProps are used to create a testing context for each test
|
||||
// deviceToUse, deviceGroupToUse and numElementsToUse are all just passed to each test function
|
||||
|
||||
extern int callTestFunctions( basefn functionList[], int numFunctions,
|
||||
const char *functionNames[],
|
||||
cl_device_id deviceToUse, int forceNoContextCreation,
|
||||
int numElementsToUse,
|
||||
int functionIndexToCall, const char *partialName, cl_command_queue_properties queueProps );
|
||||
|
||||
// This function is called by callTestFunctions, once per function, to do setup, call, logging and cleanup
|
||||
extern int callSingleTestFunction( basefn functionToCall, const char *functionName,
|
||||
cl_device_id deviceToUse, int forceNoContextCreation,
|
||||
int numElementsToUse, cl_command_queue_properties queueProps );
|
||||
|
||||
///// Miscellaneous steps
|
||||
|
||||
// Given a pre-existing device type choice, check the environment for an override, then print what
|
||||
// choice was made and how (and return the overridden choice, if there is one)
|
||||
extern void checkDeviceTypeOverride( cl_device_type *inOutType );
|
||||
|
||||
// standard callback function for context pfn_notify
|
||||
extern void CL_CALLBACK notify_callback(const char *errinfo, const void *private_info, size_t cb, void *user_data);
|
||||
|
||||
extern cl_device_type GetDeviceType( cl_device_id );
|
||||
|
||||
// Given a device (most likely passed in by the harness, but not required), will attempt to find
|
||||
// a DIFFERENT device and return it. Useful for finding another device to run multi-device tests against.
|
||||
// Note that returning NULL means an error was hit, but if no error was hit and the device passed in
|
||||
// is the only device available, the SAME device is returned, so check!
|
||||
extern cl_device_id GetOpposingDevice( cl_device_id device );
|
||||
|
||||
|
||||
extern int gFlushDenormsToZero; // This is set to 1 if the device does not support denorms (CL_FP_DENORM)
|
||||
extern int gInfNanSupport; // This is set to 1 if the device supports infinities and NaNs
|
||||
extern int gIsEmbedded; // This is set to 1 if the device is an embedded device
|
||||
extern int gHasLong; // This is set to 1 if the device suppots long and ulong types in OpenCL C.
|
||||
extern int gIsOpenCL_C_1_0_Device; // This is set to 1 if the device supports only OpenCL C 1.0.
|
||||
|
||||
#if ! defined( __APPLE__ )
|
||||
void memset_pattern4(void *, const void *, size_t);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _testHarness_h
|
||||
|
||||
|
||||
|
||||
@@ -1,51 +1,51 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "mt19937.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main( void )
|
||||
{
|
||||
MTdata d = init_genrand(42);
|
||||
int i;
|
||||
const cl_uint reference[16] = { 0x5fe1dc66, 0x8b255210, 0x0380b0c8, 0xc87d2ce4,
|
||||
0x55c31f24, 0x8bcd21ab, 0x14d5fef5, 0x9416d2b6,
|
||||
0xdf875de9, 0x00517d76, 0xd861c944, 0xa7676404,
|
||||
0x5491aff4, 0x67616209, 0xc368b3fb, 0x929dfc92 };
|
||||
int errcount = 0;
|
||||
|
||||
for( i = 0; i < 65536; i++ )
|
||||
{
|
||||
cl_uint u = genrand_int32( d );
|
||||
if( 0 == (i & 4095) )
|
||||
{
|
||||
if( u != reference[i>>12] )
|
||||
{
|
||||
printf("ERROR: expected *0x%8.8x at %d. Got 0x%8.8x\n", reference[i>>12], i, u );
|
||||
errcount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free_mtdata(d);
|
||||
|
||||
if( errcount )
|
||||
printf("mt19937 test failed.\n");
|
||||
else
|
||||
printf("mt19937 test passed.\n");
|
||||
|
||||
|
||||
return 0;
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "mt19937.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main( void )
|
||||
{
|
||||
MTdata d = init_genrand(42);
|
||||
int i;
|
||||
const cl_uint reference[16] = { 0x5fe1dc66, 0x8b255210, 0x0380b0c8, 0xc87d2ce4,
|
||||
0x55c31f24, 0x8bcd21ab, 0x14d5fef5, 0x9416d2b6,
|
||||
0xdf875de9, 0x00517d76, 0xd861c944, 0xa7676404,
|
||||
0x5491aff4, 0x67616209, 0xc368b3fb, 0x929dfc92 };
|
||||
int errcount = 0;
|
||||
|
||||
for( i = 0; i < 65536; i++ )
|
||||
{
|
||||
cl_uint u = genrand_int32( d );
|
||||
if( 0 == (i & 4095) )
|
||||
{
|
||||
if( u != reference[i>>12] )
|
||||
{
|
||||
printf("ERROR: expected *0x%8.8x at %d. Got 0x%8.8x\n", reference[i>>12], i, u );
|
||||
errcount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free_mtdata(d);
|
||||
|
||||
if( errcount )
|
||||
printf("mt19937 test failed.\n");
|
||||
else
|
||||
printf("mt19937 test passed.\n");
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,106 +1,100 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "threadTesting.h"
|
||||
#include "errorHelpers.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#if 0 // Disabed for now
|
||||
|
||||
typedef struct
|
||||
{
|
||||
basefn mFunction;
|
||||
cl_device_id mDevice;
|
||||
cl_context mContext;
|
||||
int mNumElements;
|
||||
} TestFnArgs;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Thread-based testing. Spawns a new thread to run the given test function,
|
||||
// then waits for it to complete. The entire idea is that, if the thread crashes,
|
||||
// we can catch it and report it as a failure instead of crashing the entire suite
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void *test_thread_wrapper( void *data )
|
||||
{
|
||||
TestFnArgs *args;
|
||||
int retVal;
|
||||
cl_context context;
|
||||
|
||||
args = (TestFnArgs *)data;
|
||||
|
||||
/* Create a new context to use (contexts can't cross threads) */
|
||||
context = clCreateContext(NULL, args->mDeviceGroup);
|
||||
if( context == NULL )
|
||||
{
|
||||
log_error("clCreateContext failed for new thread\n");
|
||||
return (void *)(-1);
|
||||
}
|
||||
|
||||
/* Call function */
|
||||
retVal = args->mFunction( args->mDeviceGroup, args->mDevice, context, args->mNumElements );
|
||||
|
||||
clReleaseContext( context );
|
||||
|
||||
return (void *)retVal;
|
||||
}
|
||||
|
||||
int test_threaded_function( basefn fnToTest, cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
||||
{
|
||||
int error;
|
||||
pthread_t threadHdl;
|
||||
void *retVal;
|
||||
TestFnArgs args;
|
||||
|
||||
|
||||
args.mFunction = fnToTest;
|
||||
args.mDeviceGroup = deviceGroup;
|
||||
args.mDevice = device;
|
||||
args.mContext = context;
|
||||
args.mNumElements = numElements;
|
||||
|
||||
|
||||
error = pthread_create( &threadHdl, NULL, test_thread_wrapper, (void *)&args );
|
||||
if( error != 0 )
|
||||
{
|
||||
log_error( "ERROR: Unable to create thread for testing!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Thread has been started, now just wait for it to complete (or crash) */
|
||||
error = pthread_join( threadHdl, &retVal );
|
||||
if( error != 0 )
|
||||
{
|
||||
log_error( "ERROR: Unable to join testing thread!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int)((intptr_t)retVal);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "compat.h"
|
||||
#include "threadTesting.h"
|
||||
#include "errorHelpers.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#if 0 // Disabed for now
|
||||
|
||||
typedef struct
|
||||
{
|
||||
basefn mFunction;
|
||||
cl_device_id mDevice;
|
||||
cl_context mContext;
|
||||
int mNumElements;
|
||||
} TestFnArgs;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Thread-based testing. Spawns a new thread to run the given test function,
|
||||
// then waits for it to complete. The entire idea is that, if the thread crashes,
|
||||
// we can catch it and report it as a failure instead of crashing the entire suite
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void *test_thread_wrapper( void *data )
|
||||
{
|
||||
TestFnArgs *args;
|
||||
int retVal;
|
||||
cl_context context;
|
||||
|
||||
args = (TestFnArgs *)data;
|
||||
|
||||
/* Create a new context to use (contexts can't cross threads) */
|
||||
context = clCreateContext(NULL, args->mDeviceGroup);
|
||||
if( context == NULL )
|
||||
{
|
||||
log_error("clCreateContext failed for new thread\n");
|
||||
return (void *)(-1);
|
||||
}
|
||||
|
||||
/* Call function */
|
||||
retVal = args->mFunction( args->mDeviceGroup, args->mDevice, context, args->mNumElements );
|
||||
|
||||
clReleaseContext( context );
|
||||
|
||||
return (void *)retVal;
|
||||
}
|
||||
|
||||
int test_threaded_function( basefn fnToTest, cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
|
||||
{
|
||||
int error;
|
||||
pthread_t threadHdl;
|
||||
void *retVal;
|
||||
TestFnArgs args;
|
||||
|
||||
|
||||
args.mFunction = fnToTest;
|
||||
args.mDeviceGroup = deviceGroup;
|
||||
args.mDevice = device;
|
||||
args.mContext = context;
|
||||
args.mNumElements = numElements;
|
||||
|
||||
|
||||
error = pthread_create( &threadHdl, NULL, test_thread_wrapper, (void *)&args );
|
||||
if( error != 0 )
|
||||
{
|
||||
log_error( "ERROR: Unable to create thread for testing!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Thread has been started, now just wait for it to complete (or crash) */
|
||||
error = pthread_join( threadHdl, &retVal );
|
||||
if( error != 0 )
|
||||
{
|
||||
log_error( "ERROR: Unable to join testing thread!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int)((intptr_t)retVal);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _threadTesting_h
|
||||
#define _threadTesting_h
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/opencl.h>
|
||||
#else
|
||||
#include <CL/opencl.h>
|
||||
#endif
|
||||
|
||||
#define TEST_NOT_IMPLEMENTED -99
|
||||
|
||||
typedef int (*basefn)(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_threaded_function( basefn fnToTest, cl_device_id device, cl_context context, cl_command_queue queue, int numElements );
|
||||
|
||||
#endif // _threadTesting_h
|
||||
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _threadTesting_h
|
||||
#define _threadTesting_h
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/opencl.h>
|
||||
#else
|
||||
#include <CL/opencl.h>
|
||||
#endif
|
||||
|
||||
#define TEST_NOT_IMPLEMENTED -99
|
||||
|
||||
typedef int (*basefn)(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_threaded_function( basefn fnToTest, cl_device_id device, cl_context context, cl_command_queue queue, int numElements );
|
||||
|
||||
#endif // _threadTesting_h
|
||||
|
||||
|
||||
|
||||
@@ -1,481 +1,481 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "typeWrappers.h"
|
||||
#include "kernelHelpers.h"
|
||||
#include "errorHelpers.h"
|
||||
#include <stdlib.h>
|
||||
#include "clImageHelper.h"
|
||||
|
||||
#define ROUND_SIZE_UP( _size, _align ) (((size_t)(_size) + (size_t)(_align) - 1) & -((size_t)(_align)))
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#define kPageSize 4096
|
||||
#include <sys/mman.h>
|
||||
#include <stdlib.h>
|
||||
#elif defined(__linux__)
|
||||
#include <unistd.h>
|
||||
#define kPageSize (getpagesize())
|
||||
#endif
|
||||
|
||||
clProtectedImage::clProtectedImage( cl_context context, cl_mem_flags mem_flags, const cl_image_format *fmt, size_t width, cl_int *errcode_ret )
|
||||
{
|
||||
cl_int err = Create( context, mem_flags, fmt, width );
|
||||
if( errcode_ret != NULL )
|
||||
*errcode_ret = err;
|
||||
}
|
||||
|
||||
cl_int clProtectedImage::Create( cl_context context, cl_mem_flags mem_flags, const cl_image_format *fmt, size_t width )
|
||||
{
|
||||
cl_int error;
|
||||
#if defined( __APPLE__ )
|
||||
int protect_pages = 1;
|
||||
cl_device_id devices[16];
|
||||
size_t number_of_devices;
|
||||
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(devices), devices, &number_of_devices);
|
||||
test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");
|
||||
|
||||
number_of_devices /= sizeof(cl_device_id);
|
||||
for (int i=0; i<(int)number_of_devices; i++) {
|
||||
cl_device_type type;
|
||||
error = clGetDeviceInfo(devices[i], CL_DEVICE_TYPE, sizeof(type), &type, NULL);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_TYPE failed");
|
||||
if (type == CL_DEVICE_TYPE_GPU) {
|
||||
protect_pages = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (protect_pages) {
|
||||
size_t pixelBytes = get_pixel_bytes(fmt);
|
||||
size_t rowBytes = ROUND_SIZE_UP( width * pixelBytes, kPageSize );
|
||||
size_t rowStride = rowBytes + kPageSize;
|
||||
|
||||
// create backing store
|
||||
backingStoreSize = rowStride + 8 * rowStride;
|
||||
backingStore = mmap(0, backingStoreSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0);
|
||||
|
||||
// add guard pages
|
||||
size_t row;
|
||||
char *p = (char*) backingStore;
|
||||
char *imagePtr = (char*) backingStore + 4 * rowStride;
|
||||
for( row = 0; row < 4; row++ )
|
||||
{
|
||||
mprotect( p, rowStride, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
p += rowBytes;
|
||||
mprotect( p, kPageSize, PROT_NONE ); p += rowStride;
|
||||
p -= rowBytes;
|
||||
for( row = 0; row < 4; row++ )
|
||||
{
|
||||
mprotect( p, rowStride, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
|
||||
if( getenv( "CL_ALIGN_RIGHT" ) )
|
||||
{
|
||||
static int spewEnv = 1;
|
||||
if(spewEnv)
|
||||
{
|
||||
log_info( "***CL_ALIGN_RIGHT is set. Aligning images at right edge of page\n" );
|
||||
spewEnv = 0;
|
||||
}
|
||||
imagePtr += rowBytes - pixelBytes * width;
|
||||
}
|
||||
|
||||
image = create_image_1d( context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width, rowStride, imagePtr, NULL, &error );
|
||||
} else {
|
||||
backingStore = NULL;
|
||||
image = create_image_1d( context, mem_flags, fmt, width, 0, NULL, NULL, &error );
|
||||
|
||||
}
|
||||
#else
|
||||
|
||||
backingStore = NULL;
|
||||
image = create_image_1d( context, mem_flags, fmt, width, 0, NULL, NULL, &error );
|
||||
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
clProtectedImage::clProtectedImage( cl_context context, cl_mem_flags mem_flags, const cl_image_format *fmt, size_t width, size_t height, cl_int *errcode_ret )
|
||||
{
|
||||
cl_int err = Create( context, mem_flags, fmt, width, height );
|
||||
if( errcode_ret != NULL )
|
||||
*errcode_ret = err;
|
||||
}
|
||||
|
||||
cl_int clProtectedImage::Create( cl_context context, cl_mem_flags mem_flags, const cl_image_format *fmt, size_t width, size_t height )
|
||||
{
|
||||
cl_int error;
|
||||
#if defined( __APPLE__ )
|
||||
int protect_pages = 1;
|
||||
cl_device_id devices[16];
|
||||
size_t number_of_devices;
|
||||
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(devices), devices, &number_of_devices);
|
||||
test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");
|
||||
|
||||
number_of_devices /= sizeof(cl_device_id);
|
||||
for (int i=0; i<(int)number_of_devices; i++) {
|
||||
cl_device_type type;
|
||||
error = clGetDeviceInfo(devices[i], CL_DEVICE_TYPE, sizeof(type), &type, NULL);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_TYPE failed");
|
||||
if (type == CL_DEVICE_TYPE_GPU) {
|
||||
protect_pages = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (protect_pages) {
|
||||
size_t pixelBytes = get_pixel_bytes(fmt);
|
||||
size_t rowBytes = ROUND_SIZE_UP( width * pixelBytes, kPageSize );
|
||||
size_t rowStride = rowBytes + kPageSize;
|
||||
|
||||
// create backing store
|
||||
backingStoreSize = height * rowStride + 8 * rowStride;
|
||||
backingStore = mmap(0, backingStoreSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0);
|
||||
|
||||
// add guard pages
|
||||
size_t row;
|
||||
char *p = (char*) backingStore;
|
||||
char *imagePtr = (char*) backingStore + 4 * rowStride;
|
||||
for( row = 0; row < 4; row++ )
|
||||
{
|
||||
mprotect( p, rowStride, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
p += rowBytes;
|
||||
for( row = 0; row < height; row++ )
|
||||
{
|
||||
mprotect( p, kPageSize, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
p -= rowBytes;
|
||||
for( row = 0; row < 4; row++ )
|
||||
{
|
||||
mprotect( p, rowStride, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
|
||||
if( getenv( "CL_ALIGN_RIGHT" ) )
|
||||
{
|
||||
static int spewEnv = 1;
|
||||
if(spewEnv)
|
||||
{
|
||||
log_info( "***CL_ALIGN_RIGHT is set. Aligning images at right edge of page\n" );
|
||||
spewEnv = 0;
|
||||
}
|
||||
imagePtr += rowBytes - pixelBytes * width;
|
||||
}
|
||||
|
||||
image = create_image_2d( context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width, height, rowStride, imagePtr, &error );
|
||||
} else {
|
||||
backingStore = NULL;
|
||||
image = create_image_2d( context, mem_flags, fmt, width, height, 0, NULL, &error );
|
||||
|
||||
}
|
||||
#else
|
||||
|
||||
backingStore = NULL;
|
||||
image = create_image_2d( context, mem_flags, fmt, width, height, 0, NULL, &error );
|
||||
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
clProtectedImage::clProtectedImage( cl_context context, cl_mem_flags mem_flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth, cl_int *errcode_ret )
|
||||
{
|
||||
cl_int err = Create( context, mem_flags, fmt, width, height, depth );
|
||||
if( errcode_ret != NULL )
|
||||
*errcode_ret = err;
|
||||
}
|
||||
|
||||
cl_int clProtectedImage::Create( cl_context context, cl_mem_flags mem_flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth )
|
||||
{
|
||||
cl_int error;
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
int protect_pages = 1;
|
||||
cl_device_id devices[16];
|
||||
size_t number_of_devices;
|
||||
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(devices), devices, &number_of_devices);
|
||||
test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");
|
||||
|
||||
number_of_devices /= sizeof(cl_device_id);
|
||||
for (int i=0; i<(int)number_of_devices; i++) {
|
||||
cl_device_type type;
|
||||
error = clGetDeviceInfo(devices[i], CL_DEVICE_TYPE, sizeof(type), &type, NULL);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_TYPE failed");
|
||||
if (type == CL_DEVICE_TYPE_GPU) {
|
||||
protect_pages = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (protect_pages) {
|
||||
size_t pixelBytes = get_pixel_bytes(fmt);
|
||||
size_t rowBytes = ROUND_SIZE_UP( width * pixelBytes, kPageSize );
|
||||
size_t rowStride = rowBytes + kPageSize;
|
||||
|
||||
// create backing store
|
||||
backingStoreSize = height * depth * rowStride + 8 * rowStride;
|
||||
backingStore = mmap(0, backingStoreSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0);
|
||||
|
||||
// add guard pages
|
||||
size_t row;
|
||||
char *p = (char*) backingStore;
|
||||
char *imagePtr = (char*) backingStore + 4 * rowStride;
|
||||
for( row = 0; row < 4; row++ )
|
||||
{
|
||||
mprotect( p, rowStride, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
p += rowBytes;
|
||||
for( row = 0; row < height*depth; row++ )
|
||||
{
|
||||
mprotect( p, kPageSize, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
p -= rowBytes;
|
||||
for( row = 0; row < 4; row++ )
|
||||
{
|
||||
mprotect( p, rowStride, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
|
||||
if( getenv( "CL_ALIGN_RIGHT" ) )
|
||||
{
|
||||
static int spewEnv = 1;
|
||||
if(spewEnv)
|
||||
{
|
||||
log_info( "***CL_ALIGN_RIGHT is set. Aligning images at right edge of page\n" );
|
||||
spewEnv = 0;
|
||||
}
|
||||
imagePtr += rowBytes - pixelBytes * width;
|
||||
}
|
||||
|
||||
image = create_image_3d( context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width, height, depth, rowStride, height*rowStride, imagePtr, &error );
|
||||
} else {
|
||||
backingStore = NULL;
|
||||
image = create_image_3d( context, mem_flags, fmt, width, height, depth, 0, 0, NULL, &error );
|
||||
}
|
||||
#else
|
||||
|
||||
backingStore = NULL;
|
||||
image = create_image_3d( context, mem_flags, fmt, width, height, depth, 0, 0, NULL, &error );
|
||||
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
clProtectedImage::clProtectedImage( cl_context context, cl_mem_object_type imageType, cl_mem_flags mem_flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth, size_t arraySize, cl_int *errcode_ret )
|
||||
{
|
||||
cl_int err = Create( context, imageType, mem_flags, fmt, width, height, depth, arraySize );
|
||||
if( errcode_ret != NULL )
|
||||
*errcode_ret = err;
|
||||
}
|
||||
|
||||
cl_int clProtectedImage::Create( cl_context context, cl_mem_object_type imageType, cl_mem_flags mem_flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth, size_t arraySize )
|
||||
{
|
||||
cl_int error;
|
||||
#if defined( __APPLE__ )
|
||||
int protect_pages = 1;
|
||||
cl_device_id devices[16];
|
||||
size_t number_of_devices;
|
||||
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(devices), devices, &number_of_devices);
|
||||
test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");
|
||||
|
||||
number_of_devices /= sizeof(cl_device_id);
|
||||
for (int i=0; i<(int)number_of_devices; i++) {
|
||||
cl_device_type type;
|
||||
error = clGetDeviceInfo(devices[i], CL_DEVICE_TYPE, sizeof(type), &type, NULL);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_TYPE failed");
|
||||
if (type == CL_DEVICE_TYPE_GPU) {
|
||||
protect_pages = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (protect_pages) {
|
||||
size_t pixelBytes = get_pixel_bytes(fmt);
|
||||
size_t rowBytes = ROUND_SIZE_UP( width * pixelBytes, kPageSize );
|
||||
size_t rowStride = rowBytes + kPageSize;
|
||||
|
||||
// create backing store
|
||||
switch (imageType)
|
||||
{
|
||||
case CL_MEM_OBJECT_IMAGE1D:
|
||||
backingStoreSize = rowStride + 8 * rowStride;
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE2D:
|
||||
backingStoreSize = height * rowStride + 8 * rowStride;
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE3D:
|
||||
backingStoreSize = height * depth * rowStride + 8 * rowStride;
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
||||
backingStoreSize = arraySize * rowStride + 8 * rowStride;
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
||||
backingStoreSize = height * arraySize * rowStride + 8 * rowStride;
|
||||
break;
|
||||
}
|
||||
backingStore = mmap(0, backingStoreSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0);
|
||||
|
||||
// add guard pages
|
||||
size_t row;
|
||||
char *p = (char*) backingStore;
|
||||
char *imagePtr = (char*) backingStore + 4 * rowStride;
|
||||
for( row = 0; row < 4; row++ )
|
||||
{
|
||||
mprotect( p, rowStride, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
p += rowBytes;
|
||||
size_t sz = (height > 0 ? height : 1) * (depth > 0 ? depth : 1) * (arraySize > 0 ? arraySize : 1);
|
||||
for( row = 0; row < sz; row++ )
|
||||
{
|
||||
mprotect( p, kPageSize, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
p -= rowBytes;
|
||||
for( row = 0; row < 4; row++ )
|
||||
{
|
||||
mprotect( p, rowStride, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
|
||||
if( getenv( "CL_ALIGN_RIGHT" ) )
|
||||
{
|
||||
static int spewEnv = 1;
|
||||
if(spewEnv)
|
||||
{
|
||||
log_info( "***CL_ALIGN_RIGHT is set. Aligning images at right edge of page\n" );
|
||||
spewEnv = 0;
|
||||
}
|
||||
imagePtr += rowBytes - pixelBytes * width;
|
||||
}
|
||||
|
||||
switch (imageType)
|
||||
{
|
||||
case CL_MEM_OBJECT_IMAGE1D:
|
||||
image = create_image_1d( context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width, rowStride, imagePtr, NULL, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE2D:
|
||||
image = create_image_2d( context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width, height, rowStride, imagePtr, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE3D:
|
||||
image = create_image_3d( context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width, height, depth, rowStride, height*rowStride, imagePtr, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
||||
image = create_image_1d_array( context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width, arraySize, rowStride, rowStride, imagePtr, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
||||
image = create_image_2d_array( context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width, height, arraySize, rowStride, height*rowStride, imagePtr, &error );
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
backingStore = NULL;
|
||||
switch (imageType)
|
||||
{
|
||||
case CL_MEM_OBJECT_IMAGE1D:
|
||||
image = create_image_1d( context, mem_flags, fmt, width, 0, NULL, NULL, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE2D:
|
||||
image = create_image_2d( context, mem_flags, fmt, width, height, 0, NULL, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE3D:
|
||||
image = create_image_3d( context, mem_flags, fmt, width, height, depth, 0, 0, NULL, &error );;
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
||||
image = create_image_1d_array( context, mem_flags, fmt, width, arraySize, 0, 0, NULL, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
||||
image = create_image_2d_array( context, mem_flags, fmt, width, height, arraySize, 0, 0, NULL, &error );
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
#else
|
||||
|
||||
backingStore = NULL;
|
||||
switch (imageType)
|
||||
{
|
||||
case CL_MEM_OBJECT_IMAGE1D:
|
||||
image = create_image_1d( context, mem_flags, fmt, width, 0, NULL, NULL, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE2D:
|
||||
image = create_image_2d( context, mem_flags, fmt, width, height, 0, NULL, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE3D:
|
||||
image = create_image_3d( context, mem_flags, fmt, width, height, depth, 0, 0, NULL, &error );;
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
||||
image = create_image_1d_array( context, mem_flags, fmt, width, arraySize, 0, 0, NULL, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
||||
image = create_image_2d_array( context, mem_flags, fmt, width, height, arraySize, 0, 0, NULL, &error );
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******
|
||||
* clProtectedArray implementation
|
||||
*******/
|
||||
clProtectedArray::clProtectedArray()
|
||||
{
|
||||
mBuffer = mValidBuffer = NULL;
|
||||
}
|
||||
|
||||
clProtectedArray::clProtectedArray( size_t sizeInBytes )
|
||||
{
|
||||
mBuffer = mValidBuffer = NULL;
|
||||
Allocate( sizeInBytes );
|
||||
}
|
||||
|
||||
clProtectedArray::~clProtectedArray()
|
||||
{
|
||||
if( mBuffer != NULL ) {
|
||||
#if defined( __APPLE__ )
|
||||
int error = munmap( mBuffer, mRealSize );
|
||||
if (error) log_error("WARNING: munmap failed in clProtectedArray.\n");
|
||||
#else
|
||||
free( mBuffer );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void clProtectedArray::Allocate( size_t sizeInBytes )
|
||||
{
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
|
||||
// Allocate enough space to: round up our actual allocation to an even number of pages
|
||||
// and allocate two pages on either side
|
||||
mRoundedSize = ROUND_SIZE_UP( sizeInBytes, kPageSize );
|
||||
mRealSize = mRoundedSize + kPageSize * 2;
|
||||
|
||||
// Use mmap here to ensure we start on a page boundary, so the mprotect calls will work OK
|
||||
mBuffer = (char *)mmap(0, mRealSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0);
|
||||
|
||||
mValidBuffer = mBuffer + kPageSize;
|
||||
|
||||
// Protect guard area from access
|
||||
mprotect( mValidBuffer - kPageSize, kPageSize, PROT_NONE );
|
||||
mprotect( mValidBuffer + mRoundedSize, kPageSize, PROT_NONE );
|
||||
#else
|
||||
mRoundedSize = mRealSize = sizeInBytes;
|
||||
mBuffer = mValidBuffer = (char *)calloc(1, mRealSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "typeWrappers.h"
|
||||
#include "kernelHelpers.h"
|
||||
#include "errorHelpers.h"
|
||||
#include <stdlib.h>
|
||||
#include "clImageHelper.h"
|
||||
|
||||
#define ROUND_SIZE_UP( _size, _align ) (((size_t)(_size) + (size_t)(_align) - 1) & -((size_t)(_align)))
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
#define kPageSize 4096
|
||||
#include <sys/mman.h>
|
||||
#include <stdlib.h>
|
||||
#elif defined(__linux__)
|
||||
#include <unistd.h>
|
||||
#define kPageSize (getpagesize())
|
||||
#endif
|
||||
|
||||
clProtectedImage::clProtectedImage( cl_context context, cl_mem_flags mem_flags, const cl_image_format *fmt, size_t width, cl_int *errcode_ret )
|
||||
{
|
||||
cl_int err = Create( context, mem_flags, fmt, width );
|
||||
if( errcode_ret != NULL )
|
||||
*errcode_ret = err;
|
||||
}
|
||||
|
||||
cl_int clProtectedImage::Create( cl_context context, cl_mem_flags mem_flags, const cl_image_format *fmt, size_t width )
|
||||
{
|
||||
cl_int error;
|
||||
#if defined( __APPLE__ )
|
||||
int protect_pages = 1;
|
||||
cl_device_id devices[16];
|
||||
size_t number_of_devices;
|
||||
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(devices), devices, &number_of_devices);
|
||||
test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");
|
||||
|
||||
number_of_devices /= sizeof(cl_device_id);
|
||||
for (int i=0; i<(int)number_of_devices; i++) {
|
||||
cl_device_type type;
|
||||
error = clGetDeviceInfo(devices[i], CL_DEVICE_TYPE, sizeof(type), &type, NULL);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_TYPE failed");
|
||||
if (type == CL_DEVICE_TYPE_GPU) {
|
||||
protect_pages = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (protect_pages) {
|
||||
size_t pixelBytes = get_pixel_bytes(fmt);
|
||||
size_t rowBytes = ROUND_SIZE_UP( width * pixelBytes, kPageSize );
|
||||
size_t rowStride = rowBytes + kPageSize;
|
||||
|
||||
// create backing store
|
||||
backingStoreSize = rowStride + 8 * rowStride;
|
||||
backingStore = mmap(0, backingStoreSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0);
|
||||
|
||||
// add guard pages
|
||||
size_t row;
|
||||
char *p = (char*) backingStore;
|
||||
char *imagePtr = (char*) backingStore + 4 * rowStride;
|
||||
for( row = 0; row < 4; row++ )
|
||||
{
|
||||
mprotect( p, rowStride, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
p += rowBytes;
|
||||
mprotect( p, kPageSize, PROT_NONE ); p += rowStride;
|
||||
p -= rowBytes;
|
||||
for( row = 0; row < 4; row++ )
|
||||
{
|
||||
mprotect( p, rowStride, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
|
||||
if( getenv( "CL_ALIGN_RIGHT" ) )
|
||||
{
|
||||
static int spewEnv = 1;
|
||||
if(spewEnv)
|
||||
{
|
||||
log_info( "***CL_ALIGN_RIGHT is set. Aligning images at right edge of page\n" );
|
||||
spewEnv = 0;
|
||||
}
|
||||
imagePtr += rowBytes - pixelBytes * width;
|
||||
}
|
||||
|
||||
image = create_image_1d( context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width, rowStride, imagePtr, NULL, &error );
|
||||
} else {
|
||||
backingStore = NULL;
|
||||
image = create_image_1d( context, mem_flags, fmt, width, 0, NULL, NULL, &error );
|
||||
|
||||
}
|
||||
#else
|
||||
|
||||
backingStore = NULL;
|
||||
image = create_image_1d( context, mem_flags, fmt, width, 0, NULL, NULL, &error );
|
||||
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
clProtectedImage::clProtectedImage( cl_context context, cl_mem_flags mem_flags, const cl_image_format *fmt, size_t width, size_t height, cl_int *errcode_ret )
|
||||
{
|
||||
cl_int err = Create( context, mem_flags, fmt, width, height );
|
||||
if( errcode_ret != NULL )
|
||||
*errcode_ret = err;
|
||||
}
|
||||
|
||||
cl_int clProtectedImage::Create( cl_context context, cl_mem_flags mem_flags, const cl_image_format *fmt, size_t width, size_t height )
|
||||
{
|
||||
cl_int error;
|
||||
#if defined( __APPLE__ )
|
||||
int protect_pages = 1;
|
||||
cl_device_id devices[16];
|
||||
size_t number_of_devices;
|
||||
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(devices), devices, &number_of_devices);
|
||||
test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");
|
||||
|
||||
number_of_devices /= sizeof(cl_device_id);
|
||||
for (int i=0; i<(int)number_of_devices; i++) {
|
||||
cl_device_type type;
|
||||
error = clGetDeviceInfo(devices[i], CL_DEVICE_TYPE, sizeof(type), &type, NULL);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_TYPE failed");
|
||||
if (type == CL_DEVICE_TYPE_GPU) {
|
||||
protect_pages = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (protect_pages) {
|
||||
size_t pixelBytes = get_pixel_bytes(fmt);
|
||||
size_t rowBytes = ROUND_SIZE_UP( width * pixelBytes, kPageSize );
|
||||
size_t rowStride = rowBytes + kPageSize;
|
||||
|
||||
// create backing store
|
||||
backingStoreSize = height * rowStride + 8 * rowStride;
|
||||
backingStore = mmap(0, backingStoreSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0);
|
||||
|
||||
// add guard pages
|
||||
size_t row;
|
||||
char *p = (char*) backingStore;
|
||||
char *imagePtr = (char*) backingStore + 4 * rowStride;
|
||||
for( row = 0; row < 4; row++ )
|
||||
{
|
||||
mprotect( p, rowStride, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
p += rowBytes;
|
||||
for( row = 0; row < height; row++ )
|
||||
{
|
||||
mprotect( p, kPageSize, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
p -= rowBytes;
|
||||
for( row = 0; row < 4; row++ )
|
||||
{
|
||||
mprotect( p, rowStride, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
|
||||
if( getenv( "CL_ALIGN_RIGHT" ) )
|
||||
{
|
||||
static int spewEnv = 1;
|
||||
if(spewEnv)
|
||||
{
|
||||
log_info( "***CL_ALIGN_RIGHT is set. Aligning images at right edge of page\n" );
|
||||
spewEnv = 0;
|
||||
}
|
||||
imagePtr += rowBytes - pixelBytes * width;
|
||||
}
|
||||
|
||||
image = create_image_2d( context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width, height, rowStride, imagePtr, &error );
|
||||
} else {
|
||||
backingStore = NULL;
|
||||
image = create_image_2d( context, mem_flags, fmt, width, height, 0, NULL, &error );
|
||||
|
||||
}
|
||||
#else
|
||||
|
||||
backingStore = NULL;
|
||||
image = create_image_2d( context, mem_flags, fmt, width, height, 0, NULL, &error );
|
||||
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
clProtectedImage::clProtectedImage( cl_context context, cl_mem_flags mem_flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth, cl_int *errcode_ret )
|
||||
{
|
||||
cl_int err = Create( context, mem_flags, fmt, width, height, depth );
|
||||
if( errcode_ret != NULL )
|
||||
*errcode_ret = err;
|
||||
}
|
||||
|
||||
cl_int clProtectedImage::Create( cl_context context, cl_mem_flags mem_flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth )
|
||||
{
|
||||
cl_int error;
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
int protect_pages = 1;
|
||||
cl_device_id devices[16];
|
||||
size_t number_of_devices;
|
||||
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(devices), devices, &number_of_devices);
|
||||
test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");
|
||||
|
||||
number_of_devices /= sizeof(cl_device_id);
|
||||
for (int i=0; i<(int)number_of_devices; i++) {
|
||||
cl_device_type type;
|
||||
error = clGetDeviceInfo(devices[i], CL_DEVICE_TYPE, sizeof(type), &type, NULL);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_TYPE failed");
|
||||
if (type == CL_DEVICE_TYPE_GPU) {
|
||||
protect_pages = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (protect_pages) {
|
||||
size_t pixelBytes = get_pixel_bytes(fmt);
|
||||
size_t rowBytes = ROUND_SIZE_UP( width * pixelBytes, kPageSize );
|
||||
size_t rowStride = rowBytes + kPageSize;
|
||||
|
||||
// create backing store
|
||||
backingStoreSize = height * depth * rowStride + 8 * rowStride;
|
||||
backingStore = mmap(0, backingStoreSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0);
|
||||
|
||||
// add guard pages
|
||||
size_t row;
|
||||
char *p = (char*) backingStore;
|
||||
char *imagePtr = (char*) backingStore + 4 * rowStride;
|
||||
for( row = 0; row < 4; row++ )
|
||||
{
|
||||
mprotect( p, rowStride, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
p += rowBytes;
|
||||
for( row = 0; row < height*depth; row++ )
|
||||
{
|
||||
mprotect( p, kPageSize, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
p -= rowBytes;
|
||||
for( row = 0; row < 4; row++ )
|
||||
{
|
||||
mprotect( p, rowStride, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
|
||||
if( getenv( "CL_ALIGN_RIGHT" ) )
|
||||
{
|
||||
static int spewEnv = 1;
|
||||
if(spewEnv)
|
||||
{
|
||||
log_info( "***CL_ALIGN_RIGHT is set. Aligning images at right edge of page\n" );
|
||||
spewEnv = 0;
|
||||
}
|
||||
imagePtr += rowBytes - pixelBytes * width;
|
||||
}
|
||||
|
||||
image = create_image_3d( context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width, height, depth, rowStride, height*rowStride, imagePtr, &error );
|
||||
} else {
|
||||
backingStore = NULL;
|
||||
image = create_image_3d( context, mem_flags, fmt, width, height, depth, 0, 0, NULL, &error );
|
||||
}
|
||||
#else
|
||||
|
||||
backingStore = NULL;
|
||||
image = create_image_3d( context, mem_flags, fmt, width, height, depth, 0, 0, NULL, &error );
|
||||
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
clProtectedImage::clProtectedImage( cl_context context, cl_mem_object_type imageType, cl_mem_flags mem_flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth, size_t arraySize, cl_int *errcode_ret )
|
||||
{
|
||||
cl_int err = Create( context, imageType, mem_flags, fmt, width, height, depth, arraySize );
|
||||
if( errcode_ret != NULL )
|
||||
*errcode_ret = err;
|
||||
}
|
||||
|
||||
cl_int clProtectedImage::Create( cl_context context, cl_mem_object_type imageType, cl_mem_flags mem_flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth, size_t arraySize )
|
||||
{
|
||||
cl_int error;
|
||||
#if defined( __APPLE__ )
|
||||
int protect_pages = 1;
|
||||
cl_device_id devices[16];
|
||||
size_t number_of_devices;
|
||||
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(devices), devices, &number_of_devices);
|
||||
test_error(error, "clGetContextInfo for CL_CONTEXT_DEVICES failed");
|
||||
|
||||
number_of_devices /= sizeof(cl_device_id);
|
||||
for (int i=0; i<(int)number_of_devices; i++) {
|
||||
cl_device_type type;
|
||||
error = clGetDeviceInfo(devices[i], CL_DEVICE_TYPE, sizeof(type), &type, NULL);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_TYPE failed");
|
||||
if (type == CL_DEVICE_TYPE_GPU) {
|
||||
protect_pages = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (protect_pages) {
|
||||
size_t pixelBytes = get_pixel_bytes(fmt);
|
||||
size_t rowBytes = ROUND_SIZE_UP( width * pixelBytes, kPageSize );
|
||||
size_t rowStride = rowBytes + kPageSize;
|
||||
|
||||
// create backing store
|
||||
switch (imageType)
|
||||
{
|
||||
case CL_MEM_OBJECT_IMAGE1D:
|
||||
backingStoreSize = rowStride + 8 * rowStride;
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE2D:
|
||||
backingStoreSize = height * rowStride + 8 * rowStride;
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE3D:
|
||||
backingStoreSize = height * depth * rowStride + 8 * rowStride;
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
||||
backingStoreSize = arraySize * rowStride + 8 * rowStride;
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
||||
backingStoreSize = height * arraySize * rowStride + 8 * rowStride;
|
||||
break;
|
||||
}
|
||||
backingStore = mmap(0, backingStoreSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0);
|
||||
|
||||
// add guard pages
|
||||
size_t row;
|
||||
char *p = (char*) backingStore;
|
||||
char *imagePtr = (char*) backingStore + 4 * rowStride;
|
||||
for( row = 0; row < 4; row++ )
|
||||
{
|
||||
mprotect( p, rowStride, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
p += rowBytes;
|
||||
size_t sz = (height > 0 ? height : 1) * (depth > 0 ? depth : 1) * (arraySize > 0 ? arraySize : 1);
|
||||
for( row = 0; row < sz; row++ )
|
||||
{
|
||||
mprotect( p, kPageSize, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
p -= rowBytes;
|
||||
for( row = 0; row < 4; row++ )
|
||||
{
|
||||
mprotect( p, rowStride, PROT_NONE ); p += rowStride;
|
||||
}
|
||||
|
||||
if( getenv( "CL_ALIGN_RIGHT" ) )
|
||||
{
|
||||
static int spewEnv = 1;
|
||||
if(spewEnv)
|
||||
{
|
||||
log_info( "***CL_ALIGN_RIGHT is set. Aligning images at right edge of page\n" );
|
||||
spewEnv = 0;
|
||||
}
|
||||
imagePtr += rowBytes - pixelBytes * width;
|
||||
}
|
||||
|
||||
switch (imageType)
|
||||
{
|
||||
case CL_MEM_OBJECT_IMAGE1D:
|
||||
image = create_image_1d( context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width, rowStride, imagePtr, NULL, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE2D:
|
||||
image = create_image_2d( context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width, height, rowStride, imagePtr, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE3D:
|
||||
image = create_image_3d( context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width, height, depth, rowStride, height*rowStride, imagePtr, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
||||
image = create_image_1d_array( context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width, arraySize, rowStride, rowStride, imagePtr, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
||||
image = create_image_2d_array( context, mem_flags | CL_MEM_USE_HOST_PTR, fmt, width, height, arraySize, rowStride, height*rowStride, imagePtr, &error );
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
backingStore = NULL;
|
||||
switch (imageType)
|
||||
{
|
||||
case CL_MEM_OBJECT_IMAGE1D:
|
||||
image = create_image_1d( context, mem_flags, fmt, width, 0, NULL, NULL, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE2D:
|
||||
image = create_image_2d( context, mem_flags, fmt, width, height, 0, NULL, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE3D:
|
||||
image = create_image_3d( context, mem_flags, fmt, width, height, depth, 0, 0, NULL, &error );;
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
||||
image = create_image_1d_array( context, mem_flags, fmt, width, arraySize, 0, 0, NULL, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
||||
image = create_image_2d_array( context, mem_flags, fmt, width, height, arraySize, 0, 0, NULL, &error );
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
#else
|
||||
|
||||
backingStore = NULL;
|
||||
switch (imageType)
|
||||
{
|
||||
case CL_MEM_OBJECT_IMAGE1D:
|
||||
image = create_image_1d( context, mem_flags, fmt, width, 0, NULL, NULL, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE2D:
|
||||
image = create_image_2d( context, mem_flags, fmt, width, height, 0, NULL, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE3D:
|
||||
image = create_image_3d( context, mem_flags, fmt, width, height, depth, 0, 0, NULL, &error );;
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
||||
image = create_image_1d_array( context, mem_flags, fmt, width, arraySize, 0, 0, NULL, &error );
|
||||
break;
|
||||
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
||||
image = create_image_2d_array( context, mem_flags, fmt, width, height, arraySize, 0, 0, NULL, &error );
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******
|
||||
* clProtectedArray implementation
|
||||
*******/
|
||||
clProtectedArray::clProtectedArray()
|
||||
{
|
||||
mBuffer = mValidBuffer = NULL;
|
||||
}
|
||||
|
||||
clProtectedArray::clProtectedArray( size_t sizeInBytes )
|
||||
{
|
||||
mBuffer = mValidBuffer = NULL;
|
||||
Allocate( sizeInBytes );
|
||||
}
|
||||
|
||||
clProtectedArray::~clProtectedArray()
|
||||
{
|
||||
if( mBuffer != NULL ) {
|
||||
#if defined( __APPLE__ )
|
||||
int error = munmap( mBuffer, mRealSize );
|
||||
if (error) log_error("WARNING: munmap failed in clProtectedArray.\n");
|
||||
#else
|
||||
free( mBuffer );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void clProtectedArray::Allocate( size_t sizeInBytes )
|
||||
{
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
|
||||
// Allocate enough space to: round up our actual allocation to an even number of pages
|
||||
// and allocate two pages on either side
|
||||
mRoundedSize = ROUND_SIZE_UP( sizeInBytes, kPageSize );
|
||||
mRealSize = mRoundedSize + kPageSize * 2;
|
||||
|
||||
// Use mmap here to ensure we start on a page boundary, so the mprotect calls will work OK
|
||||
mBuffer = (char *)mmap(0, mRealSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0);
|
||||
|
||||
mValidBuffer = mBuffer + kPageSize;
|
||||
|
||||
// Protect guard area from access
|
||||
mprotect( mValidBuffer - kPageSize, kPageSize, PROT_NONE );
|
||||
mprotect( mValidBuffer + mRoundedSize, kPageSize, PROT_NONE );
|
||||
#else
|
||||
mRoundedSize = mRealSize = sizeInBytes;
|
||||
mBuffer = mValidBuffer = (char *)calloc(1, mRealSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,333 +1,333 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _typeWrappers_h
|
||||
#define _typeWrappers_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
#include <stdio.h>
|
||||
#include "mt19937.h"
|
||||
#include "errorHelpers.h"
|
||||
#include "kernelHelpers.h"
|
||||
|
||||
extern "C" cl_uint gReSeed;
|
||||
extern "C" cl_uint gRandomSeed;
|
||||
|
||||
/* cl_context wrapper */
|
||||
|
||||
class clContextWrapper
|
||||
{
|
||||
public:
|
||||
clContextWrapper() { mContext = NULL; }
|
||||
clContextWrapper( cl_context program ) { mContext = program; }
|
||||
~clContextWrapper() { if( mContext != NULL ) clReleaseContext( mContext ); }
|
||||
|
||||
clContextWrapper & operator=( const cl_context &rhs ) { mContext = rhs; return *this; }
|
||||
operator cl_context() { return mContext; }
|
||||
|
||||
cl_context * operator&() { return &mContext; }
|
||||
|
||||
bool operator==( const cl_context &rhs ) { return mContext == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
cl_context mContext;
|
||||
};
|
||||
|
||||
/* cl_program wrapper */
|
||||
|
||||
class clProgramWrapper
|
||||
{
|
||||
public:
|
||||
clProgramWrapper() { mProgram = NULL; }
|
||||
clProgramWrapper( cl_program program ) { mProgram = program; }
|
||||
~clProgramWrapper() { if( mProgram != NULL ) clReleaseProgram( mProgram ); }
|
||||
|
||||
clProgramWrapper & operator=( const cl_program &rhs ) { mProgram = rhs; return *this; }
|
||||
operator cl_program() { return mProgram; }
|
||||
|
||||
cl_program * operator&() { return &mProgram; }
|
||||
|
||||
bool operator==( const cl_program &rhs ) { return mProgram == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
cl_program mProgram;
|
||||
};
|
||||
|
||||
/* cl_kernel wrapper */
|
||||
|
||||
class clKernelWrapper
|
||||
{
|
||||
public:
|
||||
clKernelWrapper() { mKernel = NULL; }
|
||||
clKernelWrapper( cl_kernel kernel ) { mKernel = kernel; }
|
||||
~clKernelWrapper() { if( mKernel != NULL ) clReleaseKernel( mKernel ); }
|
||||
|
||||
clKernelWrapper & operator=( const cl_kernel &rhs ) { mKernel = rhs; return *this; }
|
||||
operator cl_kernel() { return mKernel; }
|
||||
|
||||
cl_kernel * operator&() { return &mKernel; }
|
||||
|
||||
bool operator==( const cl_kernel &rhs ) { return mKernel == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
cl_kernel mKernel;
|
||||
};
|
||||
|
||||
/* cl_mem (stream) wrapper */
|
||||
|
||||
class clMemWrapper
|
||||
{
|
||||
public:
|
||||
clMemWrapper() { mMem = NULL; }
|
||||
clMemWrapper( cl_mem mem ) { mMem = mem; }
|
||||
~clMemWrapper() { if( mMem != NULL ) clReleaseMemObject( mMem ); }
|
||||
|
||||
clMemWrapper & operator=( const cl_mem &rhs ) { mMem = rhs; return *this; }
|
||||
operator cl_mem() { return mMem; }
|
||||
|
||||
cl_mem * operator&() { return &mMem; }
|
||||
|
||||
bool operator==( const cl_mem &rhs ) { return mMem == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
cl_mem mMem;
|
||||
};
|
||||
|
||||
class clProtectedImage
|
||||
{
|
||||
public:
|
||||
clProtectedImage() { image = NULL; backingStore = NULL; }
|
||||
clProtectedImage( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width, cl_int *errcode_ret );
|
||||
clProtectedImage( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height, cl_int *errcode_ret );
|
||||
clProtectedImage( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth, cl_int *errcode_ret );
|
||||
clProtectedImage( cl_context context, cl_mem_object_type imageType, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth, size_t arraySize, cl_int *errcode_ret );
|
||||
~clProtectedImage()
|
||||
{
|
||||
if( image != NULL )
|
||||
clReleaseMemObject( image );
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
if(backingStore)
|
||||
munmap(backingStore, backingStoreSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
cl_int Create( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width );
|
||||
cl_int Create( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height );
|
||||
cl_int Create( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth );
|
||||
cl_int Create( cl_context context, cl_mem_object_type imageType, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth, size_t arraySize );
|
||||
|
||||
clProtectedImage & operator=( const cl_mem &rhs ) { image = rhs; backingStore = NULL; return *this; }
|
||||
operator cl_mem() { return image; }
|
||||
|
||||
cl_mem * operator&() { return ℑ }
|
||||
|
||||
bool operator==( const cl_mem &rhs ) { return image == rhs; }
|
||||
|
||||
protected:
|
||||
void *backingStore;
|
||||
size_t backingStoreSize;
|
||||
cl_mem image;
|
||||
};
|
||||
|
||||
/* cl_command_queue wrapper */
|
||||
|
||||
class clCommandQueueWrapper
|
||||
{
|
||||
public:
|
||||
clCommandQueueWrapper() { mMem = NULL; }
|
||||
clCommandQueueWrapper( cl_command_queue mem ) { mMem = mem; }
|
||||
~clCommandQueueWrapper() { if( mMem != NULL ) {int error = clFinish(mMem); if (error) print_error(error, "clFinish failed"); clReleaseCommandQueue( mMem );} }
|
||||
|
||||
clCommandQueueWrapper & operator=( const cl_command_queue &rhs ) { mMem = rhs; return *this; }
|
||||
operator cl_command_queue() { return mMem; }
|
||||
|
||||
cl_command_queue * operator&() { return &mMem; }
|
||||
|
||||
bool operator==( const cl_command_queue &rhs ) { return mMem == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
cl_command_queue mMem;
|
||||
};
|
||||
|
||||
/* cl_sampler wrapper */
|
||||
class clSamplerWrapper
|
||||
{
|
||||
public:
|
||||
clSamplerWrapper() { mMem = NULL; }
|
||||
clSamplerWrapper( cl_sampler mem ) { mMem = mem; }
|
||||
~clSamplerWrapper() { if( mMem != NULL ) clReleaseSampler( mMem ); }
|
||||
|
||||
clSamplerWrapper & operator=( const cl_sampler &rhs ) { mMem = rhs; return *this; }
|
||||
operator cl_sampler() { return mMem; }
|
||||
|
||||
cl_sampler * operator&() { return &mMem; }
|
||||
|
||||
bool operator==( const cl_sampler &rhs ) { return mMem == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
cl_sampler mMem;
|
||||
};
|
||||
|
||||
/* cl_event wrapper */
|
||||
class clEventWrapper
|
||||
{
|
||||
public:
|
||||
clEventWrapper() { mMem = NULL; }
|
||||
clEventWrapper( cl_event mem ) { mMem = mem; }
|
||||
~clEventWrapper() { if( mMem != NULL ) clReleaseEvent( mMem ); }
|
||||
|
||||
clEventWrapper & operator=( const cl_event &rhs ) { mMem = rhs; return *this; }
|
||||
operator cl_event() { return mMem; }
|
||||
|
||||
cl_event * operator&() { return &mMem; }
|
||||
|
||||
bool operator==( const cl_event &rhs ) { return mMem == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
cl_event mMem;
|
||||
};
|
||||
|
||||
/* Generic protected memory buffer, for verifying access within bounds */
|
||||
class clProtectedArray
|
||||
{
|
||||
public:
|
||||
clProtectedArray();
|
||||
clProtectedArray( size_t sizeInBytes );
|
||||
virtual ~clProtectedArray();
|
||||
|
||||
void Allocate( size_t sizeInBytes );
|
||||
|
||||
operator void *() { return (void *)mValidBuffer; }
|
||||
operator const void *() const { return (const void *)mValidBuffer; }
|
||||
|
||||
protected:
|
||||
|
||||
char * mBuffer;
|
||||
char * mValidBuffer;
|
||||
size_t mRealSize, mRoundedSize;
|
||||
};
|
||||
|
||||
class RandomSeed
|
||||
{
|
||||
public:
|
||||
RandomSeed( cl_uint seed ){ if(seed) log_info( "(seed = %10.10u) ", seed ); mtData = init_genrand(seed); }
|
||||
~RandomSeed()
|
||||
{
|
||||
if( gReSeed )
|
||||
gRandomSeed = genrand_int32( mtData );
|
||||
free_mtdata(mtData);
|
||||
}
|
||||
|
||||
operator MTdata () {return mtData;}
|
||||
|
||||
protected:
|
||||
MTdata mtData;
|
||||
};
|
||||
|
||||
template <typename T> class BufferOwningPtr
|
||||
{
|
||||
BufferOwningPtr(BufferOwningPtr const &); // do not implement
|
||||
void operator=(BufferOwningPtr const &); // do not implement
|
||||
|
||||
void *ptr;
|
||||
void *map;
|
||||
size_t mapsize; // Bytes allocated total, pointed to by map.
|
||||
size_t allocsize; // Bytes allocated in unprotected pages, pointed to by ptr.
|
||||
bool aligned;
|
||||
public:
|
||||
explicit BufferOwningPtr(void *p = 0) : ptr(p), map(0), mapsize(0), allocsize(0), aligned(false) {}
|
||||
explicit BufferOwningPtr(void *p, void *m, size_t s)
|
||||
: ptr(p), map(m), mapsize(s), allocsize(0), aligned(false)
|
||||
{
|
||||
#if ! defined( __APPLE__ )
|
||||
if(m)
|
||||
{
|
||||
log_error( "ERROR: unhandled code path. BufferOwningPtr allocated with mapped buffer!" );
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
~BufferOwningPtr() {
|
||||
if (map) {
|
||||
#if defined( __APPLE__ )
|
||||
int error = munmap(map, mapsize);
|
||||
if (error) log_error("WARNING: munmap failed in BufferOwningPtr.\n");
|
||||
#endif
|
||||
} else {
|
||||
if ( aligned )
|
||||
{
|
||||
align_free(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
void reset(void *p, void *m = 0, size_t mapsize_ = 0, size_t allocsize_ = 0, bool aligned_ = false) {
|
||||
if (map){
|
||||
#if defined( __APPLE__ )
|
||||
int error = munmap(map, mapsize);
|
||||
if (error) log_error("WARNING: munmap failed in BufferOwningPtr.\n");
|
||||
#else
|
||||
log_error( "ERROR: unhandled code path. BufferOwningPtr reset with mapped buffer!" );
|
||||
abort();
|
||||
#endif
|
||||
} else {
|
||||
if ( aligned )
|
||||
{
|
||||
align_free(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
ptr = p;
|
||||
map = m;
|
||||
mapsize = mapsize_;
|
||||
allocsize = allocsize_;
|
||||
aligned = aligned_;
|
||||
#if ! defined( __APPLE__ )
|
||||
if(m)
|
||||
{
|
||||
log_error( "ERROR: unhandled code path. BufferOwningPtr allocated with mapped buffer!" );
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
operator T*() { return (T*)ptr; }
|
||||
|
||||
size_t getSize() const { return allocsize; };
|
||||
};
|
||||
|
||||
#endif // _typeWrappers_h
|
||||
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _typeWrappers_h
|
||||
#define _typeWrappers_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
#include <stdio.h>
|
||||
#include "mt19937.h"
|
||||
#include "errorHelpers.h"
|
||||
#include "kernelHelpers.h"
|
||||
|
||||
extern "C" cl_uint gReSeed;
|
||||
extern "C" cl_uint gRandomSeed;
|
||||
|
||||
/* cl_context wrapper */
|
||||
|
||||
class clContextWrapper
|
||||
{
|
||||
public:
|
||||
clContextWrapper() { mContext = NULL; }
|
||||
clContextWrapper( cl_context program ) { mContext = program; }
|
||||
~clContextWrapper() { if( mContext != NULL ) clReleaseContext( mContext ); }
|
||||
|
||||
clContextWrapper & operator=( const cl_context &rhs ) { mContext = rhs; return *this; }
|
||||
operator cl_context() { return mContext; }
|
||||
|
||||
cl_context * operator&() { return &mContext; }
|
||||
|
||||
bool operator==( const cl_context &rhs ) { return mContext == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
cl_context mContext;
|
||||
};
|
||||
|
||||
/* cl_program wrapper */
|
||||
|
||||
class clProgramWrapper
|
||||
{
|
||||
public:
|
||||
clProgramWrapper() { mProgram = NULL; }
|
||||
clProgramWrapper( cl_program program ) { mProgram = program; }
|
||||
~clProgramWrapper() { if( mProgram != NULL ) clReleaseProgram( mProgram ); }
|
||||
|
||||
clProgramWrapper & operator=( const cl_program &rhs ) { mProgram = rhs; return *this; }
|
||||
operator cl_program() { return mProgram; }
|
||||
|
||||
cl_program * operator&() { return &mProgram; }
|
||||
|
||||
bool operator==( const cl_program &rhs ) { return mProgram == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
cl_program mProgram;
|
||||
};
|
||||
|
||||
/* cl_kernel wrapper */
|
||||
|
||||
class clKernelWrapper
|
||||
{
|
||||
public:
|
||||
clKernelWrapper() { mKernel = NULL; }
|
||||
clKernelWrapper( cl_kernel kernel ) { mKernel = kernel; }
|
||||
~clKernelWrapper() { if( mKernel != NULL ) clReleaseKernel( mKernel ); }
|
||||
|
||||
clKernelWrapper & operator=( const cl_kernel &rhs ) { mKernel = rhs; return *this; }
|
||||
operator cl_kernel() { return mKernel; }
|
||||
|
||||
cl_kernel * operator&() { return &mKernel; }
|
||||
|
||||
bool operator==( const cl_kernel &rhs ) { return mKernel == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
cl_kernel mKernel;
|
||||
};
|
||||
|
||||
/* cl_mem (stream) wrapper */
|
||||
|
||||
class clMemWrapper
|
||||
{
|
||||
public:
|
||||
clMemWrapper() { mMem = NULL; }
|
||||
clMemWrapper( cl_mem mem ) { mMem = mem; }
|
||||
~clMemWrapper() { if( mMem != NULL ) clReleaseMemObject( mMem ); }
|
||||
|
||||
clMemWrapper & operator=( const cl_mem &rhs ) { mMem = rhs; return *this; }
|
||||
operator cl_mem() { return mMem; }
|
||||
|
||||
cl_mem * operator&() { return &mMem; }
|
||||
|
||||
bool operator==( const cl_mem &rhs ) { return mMem == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
cl_mem mMem;
|
||||
};
|
||||
|
||||
class clProtectedImage
|
||||
{
|
||||
public:
|
||||
clProtectedImage() { image = NULL; backingStore = NULL; }
|
||||
clProtectedImage( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width, cl_int *errcode_ret );
|
||||
clProtectedImage( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height, cl_int *errcode_ret );
|
||||
clProtectedImage( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth, cl_int *errcode_ret );
|
||||
clProtectedImage( cl_context context, cl_mem_object_type imageType, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth, size_t arraySize, cl_int *errcode_ret );
|
||||
~clProtectedImage()
|
||||
{
|
||||
if( image != NULL )
|
||||
clReleaseMemObject( image );
|
||||
|
||||
#if defined( __APPLE__ )
|
||||
if(backingStore)
|
||||
munmap(backingStore, backingStoreSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
cl_int Create( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width );
|
||||
cl_int Create( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height );
|
||||
cl_int Create( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth );
|
||||
cl_int Create( cl_context context, cl_mem_object_type imageType, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth, size_t arraySize );
|
||||
|
||||
clProtectedImage & operator=( const cl_mem &rhs ) { image = rhs; backingStore = NULL; return *this; }
|
||||
operator cl_mem() { return image; }
|
||||
|
||||
cl_mem * operator&() { return ℑ }
|
||||
|
||||
bool operator==( const cl_mem &rhs ) { return image == rhs; }
|
||||
|
||||
protected:
|
||||
void *backingStore;
|
||||
size_t backingStoreSize;
|
||||
cl_mem image;
|
||||
};
|
||||
|
||||
/* cl_command_queue wrapper */
|
||||
|
||||
class clCommandQueueWrapper
|
||||
{
|
||||
public:
|
||||
clCommandQueueWrapper() { mMem = NULL; }
|
||||
clCommandQueueWrapper( cl_command_queue mem ) { mMem = mem; }
|
||||
~clCommandQueueWrapper() { if( mMem != NULL ) {int error = clFinish(mMem); if (error) print_error(error, "clFinish failed"); clReleaseCommandQueue( mMem );} }
|
||||
|
||||
clCommandQueueWrapper & operator=( const cl_command_queue &rhs ) { mMem = rhs; return *this; }
|
||||
operator cl_command_queue() { return mMem; }
|
||||
|
||||
cl_command_queue * operator&() { return &mMem; }
|
||||
|
||||
bool operator==( const cl_command_queue &rhs ) { return mMem == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
cl_command_queue mMem;
|
||||
};
|
||||
|
||||
/* cl_sampler wrapper */
|
||||
class clSamplerWrapper
|
||||
{
|
||||
public:
|
||||
clSamplerWrapper() { mMem = NULL; }
|
||||
clSamplerWrapper( cl_sampler mem ) { mMem = mem; }
|
||||
~clSamplerWrapper() { if( mMem != NULL ) clReleaseSampler( mMem ); }
|
||||
|
||||
clSamplerWrapper & operator=( const cl_sampler &rhs ) { mMem = rhs; return *this; }
|
||||
operator cl_sampler() { return mMem; }
|
||||
|
||||
cl_sampler * operator&() { return &mMem; }
|
||||
|
||||
bool operator==( const cl_sampler &rhs ) { return mMem == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
cl_sampler mMem;
|
||||
};
|
||||
|
||||
/* cl_event wrapper */
|
||||
class clEventWrapper
|
||||
{
|
||||
public:
|
||||
clEventWrapper() { mMem = NULL; }
|
||||
clEventWrapper( cl_event mem ) { mMem = mem; }
|
||||
~clEventWrapper() { if( mMem != NULL ) clReleaseEvent( mMem ); }
|
||||
|
||||
clEventWrapper & operator=( const cl_event &rhs ) { mMem = rhs; return *this; }
|
||||
operator cl_event() { return mMem; }
|
||||
|
||||
cl_event * operator&() { return &mMem; }
|
||||
|
||||
bool operator==( const cl_event &rhs ) { return mMem == rhs; }
|
||||
|
||||
protected:
|
||||
|
||||
cl_event mMem;
|
||||
};
|
||||
|
||||
/* Generic protected memory buffer, for verifying access within bounds */
|
||||
class clProtectedArray
|
||||
{
|
||||
public:
|
||||
clProtectedArray();
|
||||
clProtectedArray( size_t sizeInBytes );
|
||||
virtual ~clProtectedArray();
|
||||
|
||||
void Allocate( size_t sizeInBytes );
|
||||
|
||||
operator void *() { return (void *)mValidBuffer; }
|
||||
operator const void *() const { return (const void *)mValidBuffer; }
|
||||
|
||||
protected:
|
||||
|
||||
char * mBuffer;
|
||||
char * mValidBuffer;
|
||||
size_t mRealSize, mRoundedSize;
|
||||
};
|
||||
|
||||
class RandomSeed
|
||||
{
|
||||
public:
|
||||
RandomSeed( cl_uint seed ){ if(seed) log_info( "(seed = %10.10u) ", seed ); mtData = init_genrand(seed); }
|
||||
~RandomSeed()
|
||||
{
|
||||
if( gReSeed )
|
||||
gRandomSeed = genrand_int32( mtData );
|
||||
free_mtdata(mtData);
|
||||
}
|
||||
|
||||
operator MTdata () {return mtData;}
|
||||
|
||||
protected:
|
||||
MTdata mtData;
|
||||
};
|
||||
|
||||
template <typename T> class BufferOwningPtr
|
||||
{
|
||||
BufferOwningPtr(BufferOwningPtr const &); // do not implement
|
||||
void operator=(BufferOwningPtr const &); // do not implement
|
||||
|
||||
void *ptr;
|
||||
void *map;
|
||||
size_t mapsize; // Bytes allocated total, pointed to by map.
|
||||
size_t allocsize; // Bytes allocated in unprotected pages, pointed to by ptr.
|
||||
bool aligned;
|
||||
public:
|
||||
explicit BufferOwningPtr(void *p = 0) : ptr(p), map(0), mapsize(0), allocsize(0), aligned(false) {}
|
||||
explicit BufferOwningPtr(void *p, void *m, size_t s)
|
||||
: ptr(p), map(m), mapsize(s), allocsize(0), aligned(false)
|
||||
{
|
||||
#if ! defined( __APPLE__ )
|
||||
if(m)
|
||||
{
|
||||
log_error( "ERROR: unhandled code path. BufferOwningPtr allocated with mapped buffer!" );
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
~BufferOwningPtr() {
|
||||
if (map) {
|
||||
#if defined( __APPLE__ )
|
||||
int error = munmap(map, mapsize);
|
||||
if (error) log_error("WARNING: munmap failed in BufferOwningPtr.\n");
|
||||
#endif
|
||||
} else {
|
||||
if ( aligned )
|
||||
{
|
||||
align_free(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
void reset(void *p, void *m = 0, size_t mapsize_ = 0, size_t allocsize_ = 0, bool aligned_ = false) {
|
||||
if (map){
|
||||
#if defined( __APPLE__ )
|
||||
int error = munmap(map, mapsize);
|
||||
if (error) log_error("WARNING: munmap failed in BufferOwningPtr.\n");
|
||||
#else
|
||||
log_error( "ERROR: unhandled code path. BufferOwningPtr reset with mapped buffer!" );
|
||||
abort();
|
||||
#endif
|
||||
} else {
|
||||
if ( aligned )
|
||||
{
|
||||
align_free(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
ptr = p;
|
||||
map = m;
|
||||
mapsize = mapsize_;
|
||||
allocsize = allocsize_;
|
||||
aligned = aligned_;
|
||||
#if ! defined( __APPLE__ )
|
||||
if(m)
|
||||
{
|
||||
log_error( "ERROR: unhandled code path. BufferOwningPtr allocated with mapped buffer!" );
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
operator T*() { return (T*)ptr; }
|
||||
|
||||
size_t getSize() const { return allocsize; };
|
||||
};
|
||||
|
||||
#endif // _typeWrappers_h
|
||||
|
||||
|
||||
|
||||
8
test_common/miniz/CMakeLists.txt
Normal file
8
test_common/miniz/CMakeLists.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
set(TARGET_NAME miniz)
|
||||
|
||||
add_library(
|
||||
${TARGET_NAME}
|
||||
STATIC
|
||||
miniz.c
|
||||
miniz.h
|
||||
)
|
||||
4153
test_common/miniz/miniz.c
Normal file
4153
test_common/miniz/miniz.c
Normal file
File diff suppressed because it is too large
Load Diff
749
test_common/miniz/miniz.h
Normal file
749
test_common/miniz/miniz.h
Normal file
@@ -0,0 +1,749 @@
|
||||
#ifndef MINIZ_HEADER_INCLUDED
|
||||
#define MINIZ_HEADER_INCLUDED
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(__TINYC__) && (defined(__linux) || defined(__linux__))
|
||||
// TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc on Linux
|
||||
#define MINIZ_NO_TIME
|
||||
#endif
|
||||
|
||||
#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS)
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__)
|
||||
// MINIZ_X86_OR_X64_CPU is only used to help set the below macros.
|
||||
#define MINIZ_X86_OR_X64_CPU 1
|
||||
#endif
|
||||
|
||||
#if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
|
||||
// Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian.
|
||||
#define MINIZ_LITTLE_ENDIAN 1
|
||||
#endif
|
||||
|
||||
#if MINIZ_X86_OR_X64_CPU
|
||||
// Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses.
|
||||
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
|
||||
#endif
|
||||
|
||||
#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__)
|
||||
// Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions).
|
||||
#define MINIZ_HAS_64BIT_REGISTERS 1
|
||||
#endif
|
||||
|
||||
// Return status codes. MZ_PARAM_ERROR is non-standard.
|
||||
enum {
|
||||
MZ_OK = 0,
|
||||
MZ_STREAM_END = 1,
|
||||
MZ_NEED_DICT = 2,
|
||||
MZ_ERRNO = -1,
|
||||
MZ_STREAM_ERROR = -2,
|
||||
MZ_DATA_ERROR = -3,
|
||||
MZ_MEM_ERROR = -4,
|
||||
MZ_BUF_ERROR = -5,
|
||||
MZ_VERSION_ERROR = -6,
|
||||
MZ_PARAM_ERROR = -10000
|
||||
};
|
||||
|
||||
typedef unsigned long mz_ulong;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// ------------------- zlib-style API Definitions.
|
||||
|
||||
// mz_free() internally uses the MZ_FREE() macro (which by default calls free() unless you've modified the MZ_MALLOC macro) to release a block allocated from the heap.
|
||||
void mz_free(void *p);
|
||||
|
||||
#define MZ_ADLER32_INIT (1)
|
||||
// mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL.
|
||||
mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len);
|
||||
|
||||
#define MZ_CRC32_INIT (0)
|
||||
// mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL.
|
||||
mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len);
|
||||
|
||||
// Compression strategies.
|
||||
enum { MZ_DEFAULT_STRATEGY = 0, MZ_FILTERED = 1, MZ_HUFFMAN_ONLY = 2, MZ_RLE = 3, MZ_FIXED = 4 };
|
||||
|
||||
// Method
|
||||
#define MZ_DEFLATED 8
|
||||
|
||||
#ifndef MINIZ_NO_ZLIB_APIS
|
||||
|
||||
// Heap allocation callbacks.
|
||||
// Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long.
|
||||
typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
|
||||
typedef void (*mz_free_func)(void *opaque, void *address);
|
||||
typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size);
|
||||
|
||||
#define MZ_VERSION "9.1.15"
|
||||
#define MZ_VERNUM 0x91F0
|
||||
#define MZ_VER_MAJOR 9
|
||||
#define MZ_VER_MINOR 1
|
||||
#define MZ_VER_REVISION 15
|
||||
#define MZ_VER_SUBREVISION 0
|
||||
|
||||
// Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs).
|
||||
enum { MZ_NO_FLUSH = 0, MZ_PARTIAL_FLUSH = 1, MZ_SYNC_FLUSH = 2, MZ_FULL_FLUSH = 3, MZ_FINISH = 4, MZ_BLOCK = 5 };
|
||||
|
||||
// Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL.
|
||||
enum { MZ_NO_COMPRESSION = 0, MZ_BEST_SPEED = 1, MZ_BEST_COMPRESSION = 9, MZ_UBER_COMPRESSION = 10, MZ_DEFAULT_LEVEL = 6, MZ_DEFAULT_COMPRESSION = -1 };
|
||||
|
||||
// Window bits
|
||||
#define MZ_DEFAULT_WINDOW_BITS 15
|
||||
|
||||
struct mz_internal_state;
|
||||
|
||||
// Compression/decompression stream struct.
|
||||
typedef struct mz_stream_s
|
||||
{
|
||||
const unsigned char *next_in; // pointer to next byte to read
|
||||
unsigned int avail_in; // number of bytes available at next_in
|
||||
mz_ulong total_in; // total number of bytes consumed so far
|
||||
|
||||
unsigned char *next_out; // pointer to next byte to write
|
||||
unsigned int avail_out; // number of bytes that can be written to next_out
|
||||
mz_ulong total_out; // total number of bytes produced so far
|
||||
|
||||
char *msg; // error msg (unused)
|
||||
struct mz_internal_state *state; // internal state, allocated by zalloc/zfree
|
||||
|
||||
mz_alloc_func zalloc; // optional heap allocation function (defaults to malloc)
|
||||
mz_free_func zfree; // optional heap free function (defaults to free)
|
||||
void *opaque; // heap alloc function user pointer
|
||||
|
||||
int data_type; // data_type (unused)
|
||||
mz_ulong adler; // adler32 of the source or uncompressed data
|
||||
mz_ulong reserved; // not used
|
||||
} mz_stream;
|
||||
|
||||
typedef mz_stream *mz_streamp;
|
||||
|
||||
// Returns the version string of miniz.c.
|
||||
const char *mz_version(void);
|
||||
|
||||
// mz_deflateInit() initializes a compressor with default options:
|
||||
// Parameters:
|
||||
// pStream must point to an initialized mz_stream struct.
|
||||
// level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION].
|
||||
// level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio.
|
||||
// (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.)
|
||||
// Return values:
|
||||
// MZ_OK on success.
|
||||
// MZ_STREAM_ERROR if the stream is bogus.
|
||||
// MZ_PARAM_ERROR if the input parameters are bogus.
|
||||
// MZ_MEM_ERROR on out of memory.
|
||||
int mz_deflateInit(mz_streamp pStream, int level);
|
||||
|
||||
// mz_deflateInit2() is like mz_deflate(), except with more control:
|
||||
// Additional parameters:
|
||||
// method must be MZ_DEFLATED
|
||||
// window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer)
|
||||
// mem_level must be between [1, 9] (it's checked but ignored by miniz.c)
|
||||
int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy);
|
||||
|
||||
// Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2().
|
||||
int mz_deflateReset(mz_streamp pStream);
|
||||
|
||||
// mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible.
|
||||
// Parameters:
|
||||
// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members.
|
||||
// flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH.
|
||||
// Return values:
|
||||
// MZ_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full).
|
||||
// MZ_STREAM_END if all input has been consumed and all output bytes have been written. Don't call mz_deflate() on the stream anymore.
|
||||
// MZ_STREAM_ERROR if the stream is bogus.
|
||||
// MZ_PARAM_ERROR if one of the parameters is invalid.
|
||||
// MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.)
|
||||
int mz_deflate(mz_streamp pStream, int flush);
|
||||
|
||||
// mz_deflateEnd() deinitializes a compressor:
|
||||
// Return values:
|
||||
// MZ_OK on success.
|
||||
// MZ_STREAM_ERROR if the stream is bogus.
|
||||
int mz_deflateEnd(mz_streamp pStream);
|
||||
|
||||
// mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH.
|
||||
mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len);
|
||||
|
||||
// Single-call compression functions mz_compress() and mz_compress2():
|
||||
// Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure.
|
||||
int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
|
||||
int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level);
|
||||
|
||||
// mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress().
|
||||
mz_ulong mz_compressBound(mz_ulong source_len);
|
||||
|
||||
// Initializes a decompressor.
|
||||
int mz_inflateInit(mz_streamp pStream);
|
||||
|
||||
// mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer:
|
||||
// window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate).
|
||||
int mz_inflateInit2(mz_streamp pStream, int window_bits);
|
||||
|
||||
// Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible.
|
||||
// Parameters:
|
||||
// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members.
|
||||
// flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH.
|
||||
// On the first call, if flush is MZ_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster).
|
||||
// MZ_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data.
|
||||
// Return values:
|
||||
// MZ_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full.
|
||||
// MZ_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified.
|
||||
// MZ_STREAM_ERROR if the stream is bogus.
|
||||
// MZ_DATA_ERROR if the deflate stream is invalid.
|
||||
// MZ_PARAM_ERROR if one of the parameters is invalid.
|
||||
// MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again
|
||||
// with more input data, or with more room in the output buffer (except when using single call decompression, described above).
|
||||
int mz_inflate(mz_streamp pStream, int flush);
|
||||
|
||||
// Deinitializes a decompressor.
|
||||
int mz_inflateEnd(mz_streamp pStream);
|
||||
|
||||
// Single-call decompression.
|
||||
// Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure.
|
||||
int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
|
||||
|
||||
// Returns a string description of the specified error code, or NULL if the error code is invalid.
|
||||
const char *mz_error(int err);
|
||||
|
||||
// Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports.
|
||||
// Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project.
|
||||
#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
|
||||
typedef unsigned char Byte;
|
||||
typedef unsigned int uInt;
|
||||
typedef mz_ulong uLong;
|
||||
typedef Byte Bytef;
|
||||
typedef uInt uIntf;
|
||||
typedef char charf;
|
||||
typedef int intf;
|
||||
typedef void *voidpf;
|
||||
typedef uLong uLongf;
|
||||
typedef void *voidp;
|
||||
typedef void *const voidpc;
|
||||
#define Z_NULL 0
|
||||
#define Z_NO_FLUSH MZ_NO_FLUSH
|
||||
#define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH
|
||||
#define Z_SYNC_FLUSH MZ_SYNC_FLUSH
|
||||
#define Z_FULL_FLUSH MZ_FULL_FLUSH
|
||||
#define Z_FINISH MZ_FINISH
|
||||
#define Z_BLOCK MZ_BLOCK
|
||||
#define Z_OK MZ_OK
|
||||
#define Z_STREAM_END MZ_STREAM_END
|
||||
#define Z_NEED_DICT MZ_NEED_DICT
|
||||
#define Z_ERRNO MZ_ERRNO
|
||||
#define Z_STREAM_ERROR MZ_STREAM_ERROR
|
||||
#define Z_DATA_ERROR MZ_DATA_ERROR
|
||||
#define Z_MEM_ERROR MZ_MEM_ERROR
|
||||
#define Z_BUF_ERROR MZ_BUF_ERROR
|
||||
#define Z_VERSION_ERROR MZ_VERSION_ERROR
|
||||
#define Z_PARAM_ERROR MZ_PARAM_ERROR
|
||||
#define Z_NO_COMPRESSION MZ_NO_COMPRESSION
|
||||
#define Z_BEST_SPEED MZ_BEST_SPEED
|
||||
#define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION
|
||||
#define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION
|
||||
#define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY
|
||||
#define Z_FILTERED MZ_FILTERED
|
||||
#define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY
|
||||
#define Z_RLE MZ_RLE
|
||||
#define Z_FIXED MZ_FIXED
|
||||
#define Z_DEFLATED MZ_DEFLATED
|
||||
#define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
|
||||
#define alloc_func mz_alloc_func
|
||||
#define free_func mz_free_func
|
||||
#define internal_state mz_internal_state
|
||||
#define z_stream mz_stream
|
||||
#define deflateInit mz_deflateInit
|
||||
#define deflateInit2 mz_deflateInit2
|
||||
#define deflateReset mz_deflateReset
|
||||
#define deflate mz_deflate
|
||||
#define deflateEnd mz_deflateEnd
|
||||
#define deflateBound mz_deflateBound
|
||||
#define compress mz_compress
|
||||
#define compress2 mz_compress2
|
||||
#define compressBound mz_compressBound
|
||||
#define inflateInit mz_inflateInit
|
||||
#define inflateInit2 mz_inflateInit2
|
||||
#define inflate mz_inflate
|
||||
#define inflateEnd mz_inflateEnd
|
||||
#define uncompress mz_uncompress
|
||||
#define crc32 mz_crc32
|
||||
#define adler32 mz_adler32
|
||||
#define MAX_WBITS 15
|
||||
#define MAX_MEM_LEVEL 9
|
||||
#define zError mz_error
|
||||
#define ZLIB_VERSION MZ_VERSION
|
||||
#define ZLIB_VERNUM MZ_VERNUM
|
||||
#define ZLIB_VER_MAJOR MZ_VER_MAJOR
|
||||
#define ZLIB_VER_MINOR MZ_VER_MINOR
|
||||
#define ZLIB_VER_REVISION MZ_VER_REVISION
|
||||
#define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION
|
||||
#define zlibVersion mz_version
|
||||
#define zlib_version mz_version()
|
||||
#endif // #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
|
||||
|
||||
#endif // MINIZ_NO_ZLIB_APIS
|
||||
|
||||
// ------------------- Types and macros
|
||||
|
||||
typedef unsigned char mz_uint8;
|
||||
typedef signed short mz_int16;
|
||||
typedef unsigned short mz_uint16;
|
||||
typedef unsigned int mz_uint32;
|
||||
typedef unsigned int mz_uint;
|
||||
typedef long long mz_int64;
|
||||
typedef unsigned long long mz_uint64;
|
||||
typedef int mz_bool;
|
||||
|
||||
#define MZ_FALSE (0)
|
||||
#define MZ_TRUE (1)
|
||||
|
||||
// An attempt to work around MSVC's spammy "warning C4127: conditional expression is constant" message.
|
||||
#ifdef _MSC_VER
|
||||
#define MZ_MACRO_END while (0, 0)
|
||||
#else
|
||||
#define MZ_MACRO_END while (0)
|
||||
#endif
|
||||
|
||||
// ------------------- ZIP archive reading/writing
|
||||
|
||||
#ifndef MINIZ_NO_ARCHIVE_APIS
|
||||
|
||||
enum
|
||||
{
|
||||
MZ_ZIP_MAX_IO_BUF_SIZE = 64*1024,
|
||||
MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 260,
|
||||
MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 256
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mz_uint32 m_file_index;
|
||||
mz_uint32 m_central_dir_ofs;
|
||||
mz_uint16 m_version_made_by;
|
||||
mz_uint16 m_version_needed;
|
||||
mz_uint16 m_bit_flag;
|
||||
mz_uint16 m_method;
|
||||
#ifndef MINIZ_NO_TIME
|
||||
time_t m_time;
|
||||
#endif
|
||||
mz_uint32 m_crc32;
|
||||
mz_uint64 m_comp_size;
|
||||
mz_uint64 m_uncomp_size;
|
||||
mz_uint16 m_internal_attr;
|
||||
mz_uint32 m_external_attr;
|
||||
mz_uint64 m_local_header_ofs;
|
||||
mz_uint32 m_comment_size;
|
||||
char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE];
|
||||
char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE];
|
||||
} mz_zip_archive_file_stat;
|
||||
|
||||
typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n);
|
||||
typedef size_t (*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n);
|
||||
|
||||
struct mz_zip_internal_state_tag;
|
||||
typedef struct mz_zip_internal_state_tag mz_zip_internal_state;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MZ_ZIP_MODE_INVALID = 0,
|
||||
MZ_ZIP_MODE_READING = 1,
|
||||
MZ_ZIP_MODE_WRITING = 2,
|
||||
MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3
|
||||
} mz_zip_mode;
|
||||
|
||||
typedef struct mz_zip_archive_tag
|
||||
{
|
||||
mz_uint64 m_archive_size;
|
||||
mz_uint64 m_central_directory_file_ofs;
|
||||
mz_uint m_total_files;
|
||||
mz_zip_mode m_zip_mode;
|
||||
|
||||
mz_uint m_file_offset_alignment;
|
||||
|
||||
mz_alloc_func m_pAlloc;
|
||||
mz_free_func m_pFree;
|
||||
mz_realloc_func m_pRealloc;
|
||||
void *m_pAlloc_opaque;
|
||||
|
||||
mz_file_read_func m_pRead;
|
||||
mz_file_write_func m_pWrite;
|
||||
void *m_pIO_opaque;
|
||||
|
||||
mz_zip_internal_state *m_pState;
|
||||
|
||||
} mz_zip_archive;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100,
|
||||
MZ_ZIP_FLAG_IGNORE_PATH = 0x0200,
|
||||
MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400,
|
||||
MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800
|
||||
} mz_zip_flags;
|
||||
|
||||
// ZIP archive reading
|
||||
|
||||
// Inits a ZIP archive reader.
|
||||
// These functions read and validate the archive's central directory.
|
||||
mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint32 flags);
|
||||
mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint32 flags);
|
||||
|
||||
#ifndef MINIZ_NO_STDIO
|
||||
mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags);
|
||||
#endif
|
||||
|
||||
// Returns the total number of files in the archive.
|
||||
mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip);
|
||||
|
||||
// Returns detailed information about an archive file entry.
|
||||
mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat);
|
||||
|
||||
// Determines if an archive file entry is a directory entry.
|
||||
mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index);
|
||||
mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index);
|
||||
|
||||
// Retrieves the filename of an archive file entry.
|
||||
// Returns the number of bytes written to pFilename, or if filename_buf_size is 0 this function returns the number of bytes needed to fully store the filename.
|
||||
mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size);
|
||||
|
||||
// Attempts to locates a file in the archive's central directory.
|
||||
// Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH
|
||||
// Returns -1 if the file cannot be found.
|
||||
int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
|
||||
|
||||
// Extracts a archive file to a memory buffer using no memory allocation.
|
||||
mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
|
||||
mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
|
||||
|
||||
// Extracts a archive file to a memory buffer.
|
||||
mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags);
|
||||
mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags);
|
||||
|
||||
// Extracts a archive file to a dynamically allocated heap buffer.
|
||||
void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags);
|
||||
void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags);
|
||||
|
||||
// Extracts a archive file using a callback function to output the file's data.
|
||||
mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
|
||||
mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
|
||||
|
||||
#ifndef MINIZ_NO_STDIO
|
||||
// Extracts a archive file to a disk file and sets its last accessed and modified times.
|
||||
// This function only extracts files, not archive directory records.
|
||||
mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags);
|
||||
mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags);
|
||||
#endif
|
||||
|
||||
// Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used.
|
||||
mz_bool mz_zip_reader_end(mz_zip_archive *pZip);
|
||||
|
||||
// ZIP archive writing
|
||||
|
||||
#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
|
||||
|
||||
// Inits a ZIP archive writer.
|
||||
mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size);
|
||||
mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size);
|
||||
|
||||
#ifndef MINIZ_NO_STDIO
|
||||
mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning);
|
||||
#endif
|
||||
|
||||
// Converts a ZIP archive reader object into a writer object, to allow efficient in-place file appends to occur on an existing archive.
|
||||
// For archives opened using mz_zip_reader_init_file, pFilename must be the archive's filename so it can be reopened for writing. If the file can't be reopened, mz_zip_reader_end() will be called.
|
||||
// For archives opened using mz_zip_reader_init_mem, the memory block must be growable using the realloc callback (which defaults to realloc unless you've overridden it).
|
||||
// Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's user provided m_pWrite function cannot be NULL.
|
||||
// Note: In-place archive modification is not recommended unless you know what you're doing, because if execution stops or something goes wrong before
|
||||
// the archive is finalized the file's central directory will be hosed.
|
||||
mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename);
|
||||
|
||||
// Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive.
|
||||
// To add a directory entry, call this method with an archive name ending in a forwardslash with empty buffer.
|
||||
// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
|
||||
mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags);
|
||||
mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32);
|
||||
|
||||
#ifndef MINIZ_NO_STDIO
|
||||
// Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive.
|
||||
// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
|
||||
mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
|
||||
#endif
|
||||
|
||||
// Adds a file to an archive by fully cloning the data from another archive.
|
||||
// This function fully clones the source file's compressed data (no recompression), along with its full filename, extra data, and comment fields.
|
||||
mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint file_index);
|
||||
|
||||
// Finalizes the archive by writing the central directory records followed by the end of central directory record.
|
||||
// After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end().
|
||||
// An archive must be manually finalized by calling this function for it to be valid.
|
||||
mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip);
|
||||
mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, size_t *pSize);
|
||||
|
||||
// Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used.
|
||||
// Note for the archive to be valid, it must have been finalized before ending.
|
||||
mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
|
||||
|
||||
// Misc. high-level helper functions:
|
||||
|
||||
// mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) appends a memory blob to a ZIP archive.
|
||||
// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
|
||||
mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
|
||||
|
||||
// Reads a single file from an archive into a heap block.
|
||||
// Returns NULL on failure.
|
||||
void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint zip_flags);
|
||||
|
||||
#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
|
||||
|
||||
#endif // #ifndef MINIZ_NO_ARCHIVE_APIS
|
||||
|
||||
// ------------------- Low-level Decompression API Definitions
|
||||
|
||||
// Decompression flags used by tinfl_decompress().
|
||||
// TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream.
|
||||
// TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input.
|
||||
// TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB).
|
||||
// TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes.
|
||||
enum
|
||||
{
|
||||
TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
|
||||
TINFL_FLAG_HAS_MORE_INPUT = 2,
|
||||
TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
|
||||
TINFL_FLAG_COMPUTE_ADLER32 = 8
|
||||
};
|
||||
|
||||
// High level decompression functions:
|
||||
// tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc().
|
||||
// On entry:
|
||||
// pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress.
|
||||
// On return:
|
||||
// Function returns a pointer to the decompressed data, or NULL on failure.
|
||||
// *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data.
|
||||
// The caller must call mz_free() on the returned block when it's no longer needed.
|
||||
void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
|
||||
|
||||
// tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory.
|
||||
// Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success.
|
||||
#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
|
||||
size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
|
||||
|
||||
// tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer.
|
||||
// Returns 1 on success or 0 on failure.
|
||||
typedef int (*tinfl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser);
|
||||
int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
|
||||
|
||||
struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor;
|
||||
|
||||
// Max size of LZ dictionary.
|
||||
#define TINFL_LZ_DICT_SIZE 32768
|
||||
|
||||
// Return status.
|
||||
typedef enum
|
||||
{
|
||||
TINFL_STATUS_BAD_PARAM = -3,
|
||||
TINFL_STATUS_ADLER32_MISMATCH = -2,
|
||||
TINFL_STATUS_FAILED = -1,
|
||||
TINFL_STATUS_DONE = 0,
|
||||
TINFL_STATUS_NEEDS_MORE_INPUT = 1,
|
||||
TINFL_STATUS_HAS_MORE_OUTPUT = 2
|
||||
} tinfl_status;
|
||||
|
||||
// Initializes the decompressor to its initial state.
|
||||
#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
|
||||
#define tinfl_get_adler32(r) (r)->m_check_adler32
|
||||
|
||||
// Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability.
|
||||
// This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output.
|
||||
tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags);
|
||||
|
||||
// Internal/private bits follow.
|
||||
enum
|
||||
{
|
||||
TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19,
|
||||
TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
|
||||
mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
|
||||
} tinfl_huff_table;
|
||||
|
||||
#if MINIZ_HAS_64BIT_REGISTERS
|
||||
#define TINFL_USE_64BIT_BITBUF 1
|
||||
#endif
|
||||
|
||||
#if TINFL_USE_64BIT_BITBUF
|
||||
typedef mz_uint64 tinfl_bit_buf_t;
|
||||
#define TINFL_BITBUF_SIZE (64)
|
||||
#else
|
||||
typedef mz_uint32 tinfl_bit_buf_t;
|
||||
#define TINFL_BITBUF_SIZE (32)
|
||||
#endif
|
||||
|
||||
struct tinfl_decompressor_tag
|
||||
{
|
||||
mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
|
||||
tinfl_bit_buf_t m_bit_buf;
|
||||
size_t m_dist_from_out_buf_start;
|
||||
tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
|
||||
mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
|
||||
};
|
||||
|
||||
// ------------------- Low-level Compression API Definitions
|
||||
|
||||
// Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently).
|
||||
#define TDEFL_LESS_MEMORY 0
|
||||
|
||||
// tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search):
|
||||
// TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression).
|
||||
enum
|
||||
{
|
||||
TDEFL_HUFFMAN_ONLY = 0, TDEFL_DEFAULT_MAX_PROBES = 128, TDEFL_MAX_PROBES_MASK = 0xFFF
|
||||
};
|
||||
|
||||
// TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data.
|
||||
// TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers).
|
||||
// TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing.
|
||||
// TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's initialization time to the minimum, but the output may vary from run to run given the same input (depending on the contents of memory).
|
||||
// TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1)
|
||||
// TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled.
|
||||
// TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables.
|
||||
// TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks.
|
||||
// The low 12 bits are reserved to control the max # of hash probes per dictionary lookup (see TDEFL_MAX_PROBES_MASK).
|
||||
enum
|
||||
{
|
||||
TDEFL_WRITE_ZLIB_HEADER = 0x01000,
|
||||
TDEFL_COMPUTE_ADLER32 = 0x02000,
|
||||
TDEFL_GREEDY_PARSING_FLAG = 0x04000,
|
||||
TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000,
|
||||
TDEFL_RLE_MATCHES = 0x10000,
|
||||
TDEFL_FILTER_MATCHES = 0x20000,
|
||||
TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000,
|
||||
TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000
|
||||
};
|
||||
|
||||
// High level compression functions:
|
||||
// tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc().
|
||||
// On entry:
|
||||
// pSrc_buf, src_buf_len: Pointer and size of source block to compress.
|
||||
// flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression.
|
||||
// On return:
|
||||
// Function returns a pointer to the compressed data, or NULL on failure.
|
||||
// *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data.
|
||||
// The caller must free() the returned block when it's no longer needed.
|
||||
void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
|
||||
|
||||
// tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory.
|
||||
// Returns 0 on failure.
|
||||
size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
|
||||
|
||||
// Compresses an image to a compressed PNG file in memory.
|
||||
// On entry:
|
||||
// pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4.
|
||||
// The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory.
|
||||
// level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL
|
||||
// If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps).
|
||||
// On return:
|
||||
// Function returns a pointer to the compressed data, or NULL on failure.
|
||||
// *pLen_out will be set to the size of the PNG image file.
|
||||
// The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed.
|
||||
void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip);
|
||||
void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out);
|
||||
|
||||
// Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time.
|
||||
typedef mz_bool (*tdefl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser);
|
||||
|
||||
// tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally.
|
||||
mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
|
||||
|
||||
enum { TDEFL_MAX_HUFF_TABLES = 3, TDEFL_MAX_HUFF_SYMBOLS_0 = 288, TDEFL_MAX_HUFF_SYMBOLS_1 = 32, TDEFL_MAX_HUFF_SYMBOLS_2 = 19, TDEFL_LZ_DICT_SIZE = 32768, TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1, TDEFL_MIN_MATCH_LEN = 3, TDEFL_MAX_MATCH_LEN = 258 };
|
||||
|
||||
// TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes).
|
||||
#if TDEFL_LESS_MEMORY
|
||||
enum { TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 12, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS };
|
||||
#else
|
||||
enum { TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 15, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS };
|
||||
#endif
|
||||
|
||||
// The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions.
|
||||
typedef enum
|
||||
{
|
||||
TDEFL_STATUS_BAD_PARAM = -2,
|
||||
TDEFL_STATUS_PUT_BUF_FAILED = -1,
|
||||
TDEFL_STATUS_OKAY = 0,
|
||||
TDEFL_STATUS_DONE = 1,
|
||||
} tdefl_status;
|
||||
|
||||
// Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums
|
||||
typedef enum
|
||||
{
|
||||
TDEFL_NO_FLUSH = 0,
|
||||
TDEFL_SYNC_FLUSH = 2,
|
||||
TDEFL_FULL_FLUSH = 3,
|
||||
TDEFL_FINISH = 4
|
||||
} tdefl_flush;
|
||||
|
||||
// tdefl's compression state structure.
|
||||
typedef struct
|
||||
{
|
||||
tdefl_put_buf_func_ptr m_pPut_buf_func;
|
||||
void *m_pPut_buf_user;
|
||||
mz_uint m_flags, m_max_probes[2];
|
||||
int m_greedy_parsing;
|
||||
mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size;
|
||||
mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end;
|
||||
mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer;
|
||||
mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, m_wants_to_finish;
|
||||
tdefl_status m_prev_return_status;
|
||||
const void *m_pIn_buf;
|
||||
void *m_pOut_buf;
|
||||
size_t *m_pIn_buf_size, *m_pOut_buf_size;
|
||||
tdefl_flush m_flush;
|
||||
const mz_uint8 *m_pSrc;
|
||||
size_t m_src_buf_left, m_out_buf_ofs;
|
||||
mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1];
|
||||
mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
|
||||
mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
|
||||
mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
|
||||
mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE];
|
||||
mz_uint16 m_next[TDEFL_LZ_DICT_SIZE];
|
||||
mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE];
|
||||
mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE];
|
||||
} tdefl_compressor;
|
||||
|
||||
// Initializes the compressor.
|
||||
// There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory.
|
||||
// pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression.
|
||||
// If pBut_buf_func is NULL the user should always call the tdefl_compress() API.
|
||||
// flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.)
|
||||
tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
|
||||
|
||||
// Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible.
|
||||
tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush);
|
||||
|
||||
// tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr.
|
||||
// tdefl_compress_buffer() always consumes the entire input buffer.
|
||||
tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush);
|
||||
|
||||
tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d);
|
||||
mz_uint32 tdefl_get_adler32(tdefl_compressor *d);
|
||||
|
||||
// Can't use tdefl_create_comp_flags_from_zip_params if MINIZ_NO_ZLIB_APIS isn't defined, because it uses some of its macros.
|
||||
#ifndef MINIZ_NO_ZLIB_APIS
|
||||
// Create tdefl_compress() flags given zlib-style compression parameters.
|
||||
// level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files)
|
||||
// window_bits may be -15 (raw deflate) or 15 (zlib)
|
||||
// strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED
|
||||
mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy);
|
||||
#endif // #ifndef MINIZ_NO_ZLIB_APIS
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MINIZ_HEADER_INCLUDED
|
||||
Reference in New Issue
Block a user