static bool test(cl_program program, cl_uint num_devices, const cl_device_id *device_list, const char *options, void (CL_CALLBACK *pfn_notify)(cl_program program, void *user_data), void *user_data, cl_int expected_error, enum piglit_result* result, const char* test_str) { cl_int errNo; errNo = clBuildProgram(program, num_devices, device_list, options, pfn_notify, user_data); if(!piglit_cl_check_error(errNo, expected_error)) { fprintf(stderr, "Failed (error code: %s): %s.\n", piglit_cl_get_error_name(errNo), test_str); piglit_merge_result(result, PIGLIT_FAIL); return false; } return true; }
PIGLIT_CL_API_TEST_CONFIG_END #if defined(CL_VERSION_1_2) static bool test(cl_command_queue queue, cl_mem image, const void *fill_color, size_t *origin, size_t *region, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event, cl_int expected_error, enum piglit_result* result, const char* test_str) { cl_int errNo; errNo = clEnqueueFillImage(queue, image, fill_color, origin, region, num_events_in_wait_list, event_wait_list, event); if(!piglit_cl_check_error(errNo, expected_error)) { fprintf(stderr, "Failed (error code: %s): %s.\n", piglit_cl_get_error_name(errNo), test_str); piglit_merge_result(result, PIGLIT_FAIL); return false; } return true; }
enum piglit_result piglit_display(void) { enum piglit_result result = PIGLIT_SKIP; int f; for (f = 0; f < NUM_FORMATS; f++) { piglit_merge_result(&result, test_fbo(&Formats[f])); } return result; }
/** * Verify that eglCreateSyncKHR() emits correct error when given a display that * does not match the display of the bound context. * * From the EGL_KHR_fence_sync spec: * * * If <type> is EGL_SYNC_FENCE_KHR and <dpy> does not match the * EGLDisplay of the currently bound context for the currently * bound client API (the EGLDisplay returned by * eglGetCurrentDisplay()) then EGL_NO_SYNC_KHR is returned and an * EGL_BAD_MATCH error is generated. * * This test strives to avoid false passes. It initializes a second display in * a second thread and binds a context there, then verifies that EGL can * successfully create and wait on fence syncs in each thread. Then, one thread * calls eglCreateSyncKHR, supplying the display bound in the other thread. * The verification step reduces the possibility that eglCreateSyncKHR fails * for some reason not under test. */ static enum piglit_result test_eglCreateSyncKHR_with_display_bound_in_other_thread(void *test_data) { enum piglit_result result = PIGLIT_PASS; enum piglit_result *t2_result = NULL; bool orig_print_tid; pthread_t thread2; int err; orig_print_tid = piglit_log_get_opt(PIGLIT_LOG_PRINT_TID); piglit_log_set_opt(PIGLIT_LOG_PRINT_TID, true); result = test_setup(); if (result != PIGLIT_PASS) { goto cleanup; } result = check_sync_in_current_context(); if (result != PIGLIT_PASS) { goto cleanup; } err = pthread_create( &thread2, NULL, thread2_create_sync_with_display_bound_in_other_thread, NULL); if (err) { piglit_loge("failed to create second thread"); result = PIGLIT_FAIL; goto cleanup; } err = pthread_join(thread2, (void**) &t2_result); if (err) { piglit_loge("failed to join thread %"PRIuMAX, (uintmax_t) thread2); result = PIGLIT_FAIL; goto cleanup; } if (t2_result) { piglit_merge_result(&result, *t2_result); } else { piglit_loge("thread %"PRIuMAX" returned no piglit_result"); result = PIGLIT_FAIL; } cleanup: free(t2_result); piglit_log_set_opt(PIGLIT_LOG_PRINT_TID, orig_print_tid); test_cleanup(EGL_NO_SYNC_KHR, &result); return result; }
enum piglit_result piglit_display(void) { enum piglit_result result = PIGLIT_SKIP; int i; glClearColor(0.5, 0.5, 0.5, 0.5); glClear(GL_COLOR_BUFFER_BIT); y_index = 0; for (i = 0; i < ARRAY_SIZE(formats); i++) { piglit_merge_result(&result, test_format(i)); } piglit_present_results(); return result; }
enum piglit_result piglit_cl_test(const int argc, const char **argv, const struct piglit_cl_custom_test_config *config, const struct piglit_cl_custom_test_env *env) { piglit_cl_context context = NULL; cl_program program = NULL; unsigned i, j; static const cl_mem_flags possibilities[] = { #ifdef CL_VERSION_1_2 0, #endif CL_MEM_USE_HOST_PTR, CL_MEM_COPY_HOST_PTR, CL_MEM_ALLOC_HOST_PTR, CL_MEM_COPY_HOST_PTR | CL_MEM_ALLOC_HOST_PTR, }; const size_t nump = ARRAY_SIZE(possibilities); enum piglit_result part_ret, ret = PIGLIT_PASS; float data = 10; context = piglit_cl_create_context(env->platform_id, &env->device_id, 1); program = piglit_cl_build_program_with_source(context, 1, &source, NULL); for (i = 0; i < nump; ++i) for (j = 0; j < nump; ++j) { part_ret = buffer_test(&context, &program, possibilities[i], possibilities[j], ++data); piglit_merge_result(&ret, part_ret); } clReleaseProgram(program); piglit_cl_release_context(context); return ret; }
void piglit_init(int argc, char **argv) { GLuint tex; int i, texf; enum piglit_result result = PIGLIT_SKIP; /* Note: We test later extensions by testing them against all * combinations of (storage format, read format) including the * formats from previous extensions. */ for (i = 1; i < argc; i++) { if (strcmp(argv[i], "GL_ARB_texture_rg") == 0) { piglit_require_extension(argv[i]); test_rg = true; } else if (strcmp(argv[i], "GL_ARB_texture_rgb10_a2ui") == 0) { piglit_require_extension(argv[i]); test_rg = true; test_rgb10_a2ui = true; } else { usage(); exit(1); } } piglit_require_extension("GL_EXT_texture_integer"); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); for (texf = 0; texf < ARRAY_SIZE(formats); texf++) piglit_merge_result(&result, test_format(&formats[texf])); piglit_report_result(result); }
enum piglit_result piglit_display(void) { enum piglit_result result = PIGLIT_SKIP; int i; GLuint vao, vbo; glClearColor(0.5, 0.5, 0.5, 0.5); glClear(GL_COLOR_BUFFER_BIT); y_index = 0; /* For GL core, we need to have a vertex array object bound. * Otherwise, we don't particularly have to. Always use a * vertex buffer object, though. */ glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER_ARB, vbo); if (piglit_get_gl_version() >= 31) { GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); } glVertexAttribPointer(vertex_location, 2, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(vertex_location); for (i = 0; i < ARRAY_SIZE(formats); i++) { piglit_merge_result(&result, test_format(i)); } glDeleteBuffers(1, &vbo); glDeleteVertexArrays(1, &vao); piglit_present_results(); return result; }
static bool test(cl_context context, cl_uint num_devices, const cl_device_id *device_list, const char *options, cl_uint num_input_programs, const cl_program *input_programs, void (CL_CALLBACK *pfn_notify)(cl_program program, void *user_data), void *user_data, cl_program *ret_program, cl_int expected_error, enum piglit_result* result, const char* test_str) { cl_program program; cl_int errNo; program = clLinkProgram(context, num_devices, device_list, options, num_input_programs, input_programs, pfn_notify, user_data, &errNo); if (ret_program) { *ret_program = program; } else { if (program) clReleaseProgram(program); } if(!piglit_cl_check_error(errNo, expected_error)) { fprintf(stderr, "Failed (error code: %s): %s.\n", piglit_cl_get_error_name(errNo), test_str); piglit_merge_result(result, PIGLIT_FAIL); return false; } return true; }
enum piglit_result piglit_cl_test(const int argc, const char** argv, const struct piglit_cl_api_test_config* config, const struct piglit_cl_api_test_env* env) { enum piglit_result result = PIGLIT_PASS; int i; cl_int errNo; cl_uint num_devices; cl_device_id* devices; cl_context cl_ctx; bool found_invalid_platform = false; cl_platform_id* platform_ids; unsigned int num_platform_ids; cl_platform_id invalid_platform_id; //TODO: test also CL_CONTEXT_INTEROP_USER_SYNC cl_context_properties context_properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)env->platform_id, 0 }; cl_context_properties invalid_context_properties[] = { CL_DEVICE_NAME, (cl_context_properties)env->platform_id, 0 }; cl_context_properties invalid_platform_context_properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)NULL, 0 }; cl_context_properties multiple_platform_context_properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)env->platform_id, CL_CONTEXT_PLATFORM, (cl_context_properties)env->platform_id, 0 }; /* Find invalid platform_id */ invalid_platform_id = 0; num_platform_ids = piglit_cl_get_platform_ids(&platform_ids); while(!found_invalid_platform) { found_invalid_platform = true; invalid_platform_id = (cl_platform_id)1; for(i = 0; i < num_platform_ids; i++) { if(invalid_platform_id == platform_ids[i]) { found_invalid_platform = false; break; } } } free(platform_ids); invalid_platform_context_properties[1] = (cl_context_properties)invalid_platform_id; /*** Normal usage ***/ /* get device ids */ num_devices = piglit_cl_get_device_ids(env->platform_id, CL_DEVICE_TYPE_ALL, &devices); /* * Create context. * Try creating context from 1 to num_devices devices. */ for(i = 1; i <= num_devices; i++) { test(context_properties, i, devices, NULL, NULL, CL_SUCCESS, &result, "Create context"); //TODO: test callback functions } /*** Errors ***/ /* * CL_INVALID_PLATFORM if properties is NULL and no platform * could be selected or if platform value specified in properties * is not a valid platform. * * Note: Can not test implementation-defined behaviour on * NULL context_properties. */ cl_ctx = clCreateContext(invalid_platform_context_properties, num_devices, devices, NULL, NULL, &errNo); if( errNo != CL_INVALID_PLATFORM #if defined(CL_VERSION_1_1) && errNo != CL_INVALID_PROPERTY #endif ) { test(invalid_platform_context_properties, num_devices, devices, NULL, NULL, CL_INVALID_PLATFORM, &result, "Trigger CL_INVALID_PLATFORM if platform value specified in properties is not a valid platform"); #if defined(CL_VERSION_1_1) printf("Another valid expected CL error: %d\n", CL_INVALID_PROPERTY); #endif piglit_merge_result(&result, PIGLIT_FAIL); } else if (cl_ctx != NULL) { test(invalid_platform_context_properties, num_devices, devices, NULL, NULL, CL_INVALID_PLATFORM, &result, "Trigger CL_INVALID_PLATFORM if platform value specified in properties is not a valid platform"); } /* * CL_INVALID_VALUE if context property name in properties is * not a supported property name; if devices is NULL; if * num_devices is equal to zero; or if pfn_notify is NULL but * user_data is not NULL. * * Version: 1.0 * * CL_INVALID_VALUE if devices is NULL; if num_devices is equal * to zero; or if pfn_notify is NULL but user_data is not NULL. * * Version: 1.1 */ if(env->version <= 10) { test(invalid_context_properties, num_devices, devices, NULL, NULL, CL_INVALID_VALUE, &result, "Trigger CL_INVALID_VALUE if context property name in properties is not a supported property name"); } test(context_properties, num_devices, NULL, NULL, NULL, CL_INVALID_VALUE, &result, "Trigger CL_INVALID_VALUE if devices is NULL"); test(context_properties, 0, devices, NULL, NULL, CL_INVALID_VALUE, &result, "Trigger CL_INVALID_VALUE if num_devices is equal to zero"); test(context_properties, num_devices, devices, NULL, &context_properties, CL_INVALID_VALUE, &result, "Trigger CL_INVALID_VALUE if pfn_notify is NULL but user_data is not NULL"); /* * CL_INVALID_PROPERTY if context property name in properties * is not a supported property name, if the value specified for * a supported property name is not valid, or if the same * property name is specified more than once. * * Version: 1.1 * * Note: 'if the value specified for a supported property name is * not valid' was already tested */ #if defined(CL_VERSION_1_1) if(env->version >= 11) { test(invalid_context_properties, num_devices, devices, NULL, NULL, CL_INVALID_PROPERTY, &result, "Trigger CL_INVALID_PROPERTY if context property name in poperties is not a supported property name"); test(multiple_platform_context_properties, num_devices, devices, NULL, NULL, CL_INVALID_PROPERTY, &result, "Trigger CL_INVALID_PROPERTY if the same property is specified more than once"); } #endif /* * CL_INVALID_DEVICE if devices contains an invalid device * or are not associated with the specified platform. * * TODO: implement */ /* * CL_DEVICE_NOT_AVAILABLE if a device in devices is currently * not available even though the device was returned by clGetDeviceIDs. * * Note: Can not test */ free(devices); return result; }
static enum piglit_result test_format(const struct format_info *info) { int num_texels = ARRAY_SIZE(texels_s); uint32_t texels[ARRAY_SIZE(texels_s)][4]; GLenum type; int lbits, abits, ibits, rbits, gbits, bbits; int i, readf; enum piglit_result result = PIGLIT_SKIP; if (!test_rg && ((info->base_format == GL_RED_INTEGER && !strstr(info->name, "GL_INTENSITY")) || info->base_format == GL_RG_INTEGER)) { return PIGLIT_SKIP; } if (!test_rgb10_a2ui && info->internal_format == GL_RGB10_A2UI) return PIGLIT_SKIP; /* FINISHME: We only test conversion from large signed to * small signed or large unsigned to small unsigned. The * rules just say that when reading pixels, the value is * clamped to the representable range, not how/when sign * extension occurs, and whether the clamping applies before * or after */ if (!strstr(info->name, "32")) return PIGLIT_SKIP; if (info->sign) { memcpy(texels, texels_s, sizeof(texels_s)); type = GL_INT; } else { memcpy(texels, texels_u, sizeof(texels_u)); type = GL_UNSIGNED_INT; } glTexImage2D(GL_TEXTURE_2D, 0, info->internal_format, num_texels, 1, 0, GL_RGBA_INTEGER_EXT, type, texels); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_LUMINANCE_SIZE, &lbits); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &abits); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTENSITY_SIZE, &ibits); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &rbits); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &gbits); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &bbits); /* Compute the RGBA channels that should be read from the * texture given the input RGBA texels we gave. See Table 6.1 * ("Texture, table, and filter return values") of the GL 3.0 * specification. Note that input R is always mapped to L or * I, and comes back out in R (except for ALPHA). */ if (ibits || lbits) { for (i = 0; i < num_texels; i++) { texels[i][1] = 0; texels[i][2] = 0; } } else { if (!rbits) { for (i = 0; i < num_texels; i++) texels[i][0] = 0; } if (!gbits) { for (i = 0; i < num_texels; i++) texels[i][1] = 0; } if (!bbits) { for (i = 0; i < num_texels; i++) texels[i][2] = 0; } } /* Everybody's consistent on A bits in table 6.1. */ if (!abits) { for (i = 0; i < num_texels; i++) texels[i][3] = 1; } for (readf = 0; readf < ARRAY_SIZE(read_formats); readf++) { piglit_merge_result(&result, read_format(info, &read_formats[readf], texels, num_texels)); if (result == PIGLIT_FAIL) return result; } return result; }
PIGLIT_CL_API_TEST_CONFIG_END enum piglit_result piglit_cl_test(const int argc, const char** argv, const struct piglit_cl_api_test_config* config, const struct piglit_cl_api_test_env* env) { enum piglit_result result = PIGLIT_PASS; int i; cl_int errNo; size_t param_value_size; void* param_value; bool found_invalid_platform = false; cl_platform_id* platform_ids; unsigned int num_platform_ids; cl_platform_id invalid_platform_id; int num_platform_infos = PIGLIT_CL_ENUM_NUM(cl_platform_info, env->version); const cl_platform_info *platform_infos = PIGLIT_CL_ENUM_ARRAY(cl_platform_info); /* Find invalid platform_id */ invalid_platform_id = 0; num_platform_ids = piglit_cl_get_platform_ids(&platform_ids); while(!found_invalid_platform) { found_invalid_platform = true; invalid_platform_id = (cl_platform_id)1; for(i = 0; i < num_platform_ids; i++) { if(invalid_platform_id == platform_ids[i]) { found_invalid_platform = false; break; } } } free(platform_ids); /*** Normal usage ***/ for(i = 0; i < num_platform_infos; i++) { printf("%s: ", piglit_cl_get_enum_name(platform_infos[i])); errNo = clGetPlatformInfo(env->platform_id, platform_infos[i], 0, NULL, ¶m_value_size); if(!piglit_cl_check_error(errNo, CL_SUCCESS)) { fprintf(stderr, "Failed (error code: %s): Get size of %s.\n", piglit_cl_get_error_name(errNo), piglit_cl_get_enum_name(platform_infos[i])); piglit_merge_result(&result, PIGLIT_FAIL); continue; } param_value = malloc(param_value_size); errNo = clGetPlatformInfo(env->platform_id, platform_infos[i], param_value_size, param_value, NULL); if(!piglit_cl_check_error(errNo, CL_SUCCESS)) { fprintf(stderr, "Failed (error code: %s): Get value of %s.\n", piglit_cl_get_error_name(errNo), piglit_cl_get_enum_name(platform_infos[i])); piglit_merge_result(&result, PIGLIT_FAIL); } printf("%s\n", (char*)param_value); free(param_value); } /*** Errors **/ /* * CL_INVALID_VALUE if param_name is not one of the supported * values or if size in bytes specified by param_value_size is * less than size of return type and param_value is not a NULL * value. */ errNo = clGetPlatformInfo(env->platform_id, CL_PLATFORM_PROFILE, 1, param_value, NULL); if(!piglit_cl_check_error(errNo, CL_INVALID_VALUE)) { fprintf(stderr, "Failed (error code: %s): Trigger CL_INVALID_VALUE if param_name is not one of the supported values.\n", piglit_cl_get_error_name(errNo)); piglit_merge_result(&result, PIGLIT_FAIL); } errNo = clGetPlatformInfo(env->platform_id, CL_DEVICE_NAME, 0, NULL, ¶m_value_size); if(!piglit_cl_check_error(errNo, CL_INVALID_VALUE)) { fprintf(stderr, "Failed (error code: %s): Trigger CL_INVALID_VALUE if size in bytes specified by param_value is less than size of return type and param_value is not a NULL value.\n", piglit_cl_get_error_name(errNo)); piglit_merge_result(&result, PIGLIT_FAIL); } return result; }
enum piglit_result piglit_cl_test(const int argc, const char** argv, const struct piglit_cl_api_test_config* config, const struct piglit_cl_api_test_env* env) { enum piglit_result result = PIGLIT_PASS; char test_str[1024]; int i; int mask; cl_ulong alloc_size = BUFFER_SIZE; // max alloc size per device >= 128*1024*1024 cl_ulong max_alloc; unsigned char host_buffer[BUFFER_SIZE]; unsigned char host_buffer_read[BUFFER_SIZE]; cl_mem_flags mixed_mem_flags; int num_mem_flags = PIGLIT_CL_ENUM_NUM(cl_mem_flags, env->version); const cl_mem_flags* mem_flags = PIGLIT_CL_ENUM_ARRAY(cl_mem_flags); int num_mutexes = PIGLIT_CL_ENUM_NUM(cl_mem_flags_mutexes, env->version); const cl_mem_flags* mutexes = PIGLIT_CL_ENUM_ARRAY(cl_mem_flags_mutexes); /*** Normal usage ***/ for (i = 0; i < BUFFER_SIZE; i++){ host_buffer[i] = (unsigned char)i; } /* * For each memory flags mix. * There are 2^(num_mem_flags)-1 possible options without * excluding mutually exclusive options. */ for(mask = 1; mask < (1 << num_mem_flags); mask++) { mixed_mem_flags = get_mixed_mem_flags(mask, mem_flags); /* exclude invalid mixes */ if(!mem_flags_valid(mixed_mem_flags, num_mutexes, mutexes)) { continue; } sprintf(test_str, "Create buffer using 0x%X as memory flags", (unsigned int)mixed_mem_flags); if( (mixed_mem_flags & CL_MEM_USE_HOST_PTR) || (mixed_mem_flags & CL_MEM_COPY_HOST_PTR)) { cl_mem buffer; /* test if function returns right values */ test(env->context->cl_ctx, mixed_mem_flags, alloc_size, host_buffer, CL_SUCCESS, &result, test_str); /* test if buffer gets initialized properly */ buffer = clCreateBuffer(env->context->cl_ctx, mixed_mem_flags, alloc_size, host_buffer, NULL); if(buffer) { cl_int errNo; errNo = clEnqueueReadBuffer(env->context->command_queues[0], buffer, true, 0, alloc_size, host_buffer_read, 0, NULL, NULL); if(errNo == CL_SUCCESS) { for(i = 0; i < BUFFER_SIZE; i++) { if(host_buffer[i] != host_buffer_read[i]) { printf("Buffer data was not initialized properly.\n"); fprintf(stderr, "Buffer data was not properly initialized using 0x%X as memory flags.\n", (unsigned int)mixed_mem_flags); piglit_merge_result(&result, PIGLIT_FAIL); break; } } } } } else { test(env->context->cl_ctx, mixed_mem_flags, alloc_size, NULL, CL_SUCCESS, &result, test_str); } } #if defined(CL_VERSION_1_2) if(env->version >= 12) { test(env->context->cl_ctx, 0, // defaults to CL_MEM_READ_WRITE alloc_size, NULL, CL_SUCCESS, &result, "Create buffer using 0 (defaults to CL_MEM_READ_WRITE) as memory flags"); } #endif //CL_VERSION_1_2 /*** Errors ***/ /* * CL_INVALID_CONTEXT if context is not a valid context. */ test(NULL, CL_MEM_READ_WRITE, alloc_size, NULL, CL_INVALID_CONTEXT, &result, "Trigger CL_INVALID_CONTEXT if context is not a valid context"); /* * CL_INVALID_VALUE if values specified in flags are not valid. */ for(mask = 1; mask < (1 << num_mem_flags); mask++) { mixed_mem_flags = get_mixed_mem_flags(mask, mem_flags); /* only invalid mixes */ if(!mem_flags_valid(mixed_mem_flags, num_mutexes, mutexes)) { sprintf(test_str, "Trigger CL_INVALID_VALUE if values specified in flags are not valid (using 0x%X as memory flags)", (unsigned int)mixed_mem_flags); if( (mixed_mem_flags & CL_MEM_USE_HOST_PTR) || (mixed_mem_flags & CL_MEM_COPY_HOST_PTR)) { test(env->context->cl_ctx, mixed_mem_flags, alloc_size, host_buffer, CL_INVALID_VALUE, &result, test_str); } else { test(env->context->cl_ctx, mixed_mem_flags, alloc_size, NULL, CL_INVALID_VALUE, &result, test_str); } } } /* * CL_INVALID_BUFFER_SIZE if size is 0 or is greater than * CL_DEVICE_MAX_MEM_ALLOC_SIZE value specified in table of * OpenCL Device Queries for clGetDeviceInfo for all devices * in context. */ test(env->context->cl_ctx, CL_MEM_READ_WRITE, 0, NULL, CL_INVALID_BUFFER_SIZE, &result, "Trigger CL_INVALID_BUFFER_SIZE if size is 0"); max_alloc = 0; for(i = 0; i < env->context->num_devices; i++) { cl_ulong* max_device_alloc; max_device_alloc = piglit_cl_get_device_info(env->context->device_ids[i], CL_DEVICE_MAX_MEM_ALLOC_SIZE); if(*max_device_alloc > max_alloc) { max_alloc = *max_device_alloc; } free(max_device_alloc); } test(env->context->cl_ctx, CL_MEM_READ_WRITE, max_alloc+1, // if we get to overflow, we're back at 0 and errNo must be the same NULL, CL_INVALID_BUFFER_SIZE, &result, "Trigger CL_INVALID_BUFFER_SIZE if size is greater than CL_DEVICE_MAX_MEM_ALLOC_SIZE"); /* * CL_INVALID_HOST_PTR if host_ptr is NULL and CL_MEM_USE_HOST_PTR * or CL_MEM_COPY_HOST_PTR are set in flags or if host_ptr is not * NULL but CL_MEM_COPY_HOST_PTR or CL_MEM_USE_HOST_PTR are not * set in flags. */ test(env->context->cl_ctx, CL_MEM_USE_HOST_PTR, alloc_size, NULL, CL_INVALID_HOST_PTR, &result, "Trigger CL_INVALID_HOST_PTR if host_ptr is NULL and CL_MEM_USE_HOST_PTR is set in flags"); test(env->context->cl_ctx, CL_MEM_COPY_HOST_PTR, alloc_size, NULL, CL_INVALID_HOST_PTR, &result, "Trigger CL_INVALID_HOST_PTR if host_ptr is NULL and CL_MEM_COPY_HOST_PTR is set in flags"); test(env->context->cl_ctx, CL_MEM_READ_WRITE, alloc_size, host_buffer, CL_INVALID_HOST_PTR, &result, "Trigger CL_INVALID_HOST_PTR if host_ptr is not NULL CL_MEM_USE_HOST_PTR or CL_MEM_COPY_HOST_PTR are not set in flags"); return result; }
PIGLIT_CL_API_TEST_CONFIG_END #define BUFFER_SIZE 512 static void test(cl_context cl_ctx, cl_mem_flags flags, size_t size, void *host_ptr, cl_int expected_error, enum piglit_result* result, char* test_str) { cl_int errNo; cl_mem buffer; /* with errNo */ buffer = clCreateBuffer(cl_ctx, flags, size, host_ptr, &errNo); if(!piglit_cl_check_error(errNo, expected_error)) { fprintf(stderr, "Failed (error code: %s): %s.\n", piglit_cl_get_error_name(errNo), test_str); piglit_merge_result(result, PIGLIT_FAIL); return; } if(expected_error == CL_SUCCESS) { if(buffer == NULL) { printf("Expecting non-NULL cl_mem\n"); fprintf(stderr, "Failed (NULL value returned): %s.\n", test_str); piglit_merge_result(result, PIGLIT_FAIL); return; } clReleaseMemObject(buffer); } else if (buffer != NULL) { printf("Expecting NULL cl_mem\n"); fprintf(stderr, "Failed (non-NULL value returned): %s.\n", test_str); piglit_merge_result(result, PIGLIT_FAIL); return; } /* without errNo */ buffer = clCreateBuffer(cl_ctx, flags, size, host_ptr, NULL); if(expected_error == CL_SUCCESS) { if(buffer == NULL) { printf("Expecting non-NULL cl_mem\n"); fprintf(stderr, "Failed (NULL value returned): %s.\n", test_str); piglit_merge_result(result, PIGLIT_FAIL); return; } clReleaseMemObject(buffer); } else if (buffer != NULL) { printf("Expecting NULL cl_mem\n"); fprintf(stderr, "Failed (non-NULL value returned): %s.\n", test_str); piglit_merge_result(result, PIGLIT_FAIL); return; } }
static enum piglit_result draw(Display *dpy) { enum piglit_result result = PIGLIT_PASS; int64_t last_ust = 0xd0, last_msc = 0xd0, last_sbc = 0xd0; int64_t last_timestamp = -1; struct stats msc_wallclock_duration_stats = {}; struct stats msc_ust_duration_stats = {}; double expected_msc_wallclock_duration = 0.0; int32_t rate_num, rate_den; unsigned int i; if (!glXGetSyncValuesOML(dpy, win, &last_ust, &last_msc, &last_sbc)) { fprintf(stderr, "Initial glXGetSyncValuesOML failed\n"); return PIGLIT_FAIL; } /* Check that the window is fresh */ if (last_sbc != 0) { fprintf(stderr, "Initial SBC for the window should be 0, was " "%" PRId64 "\n", last_sbc); piglit_merge_result(&result, PIGLIT_WARN); } if (!glXGetMscRateOML(dpy, win, &rate_num, &rate_den)) { fprintf(stderr, "glXGetMscRateOML failed, can't test MSC duration\n"); piglit_merge_result(&result, PIGLIT_WARN); } else { expected_msc_wallclock_duration = 1e6 * rate_den / rate_num; } piglit_set_timeout(5, PIGLIT_FAIL); for (i = 0; i < loops; i++) { int64_t new_ust = 0xd0, new_msc = 0xd0, new_sbc = 0xd0; int64_t check_ust = 0xd0, check_msc = 0xd0, check_sbc = 0xd0; int64_t new_timestamp; int64_t expected_msc, target_sbc; int64_t target_msc = 0; if (target_msc_delta) { target_msc = last_msc + target_msc_delta; } if (use_swapbuffers) { glClearColor(0.0, 1.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); target_sbc = glXSwapBuffersMscOML(dpy, win, target_msc, divisor, msc_remainder); if(target_sbc <= 0) { fprintf(stderr, "SwapBuffersMscOML failed\n"); return PIGLIT_FAIL; } if(target_sbc != last_sbc + 1) { fprintf(stderr, "glXSwapBuffersMscOML calculated the" " wrong target sbc: expected %"PRId64 " but got %"PRId64"\n", last_sbc + 1, target_sbc); result = PIGLIT_FAIL; } if(!glXWaitForSbcOML(dpy, win, target_sbc, &new_ust, &new_msc, &new_sbc)) { fprintf(stderr, "glXWaitForSbcOML failed\n"); result = PIGLIT_FAIL; } } else { target_sbc = last_sbc; if(!glXWaitForMscOML(dpy, win, target_msc, divisor, msc_remainder, &new_ust, &new_msc, &new_sbc)) { fprintf(stderr, "glXWaitForSbcOML failed\n"); result = PIGLIT_FAIL; } } new_timestamp = piglit_get_microseconds(); if (!glXGetSyncValuesOML(dpy, win, &check_ust, &check_msc, &check_sbc)) { fprintf(stderr, "Follow-up GetSyncValuesOML failed\n"); return PIGLIT_FAIL; } if (new_ust < last_ust) { fprintf(stderr, "iteration %u: non-monotonic UST went " "backward by %"PRId64" during Wait\n", i, last_ust - new_ust); result = PIGLIT_FAIL; /* Wait returned something bogus, but GetSyncValues * usually works, so try evaluating the rest of the * tests using the check values. */ new_ust = check_ust; } if (check_ust < new_ust) { fprintf(stderr, "iteration %u: non-monotonic UST went " "backward by %"PRId64" across GetSyncValues\n", i, last_ust - check_ust); result = PIGLIT_FAIL; } if (new_msc < last_msc) { fprintf(stderr, "iteration %u: non-monotonic MSC went " "backward by %"PRId64" during Wait\n", i, last_msc - new_msc); result = PIGLIT_FAIL; /* Wait returned something bogus, but GetSyncValues * usually works, so try evaluating the rest of the * tests using the check values. */ new_msc = check_msc; } if (check_msc < new_msc) { fprintf(stderr, "iteration %u: non-monotonic MSC went " "backward by %"PRId64" across GetSyncValues\n", i, last_msc - check_msc); result = PIGLIT_FAIL; } if (new_sbc != target_sbc) { fprintf(stderr, "iteration %u: Wait should have " "returned at SBC %"PRId64" but returned at " "%"PRId64"\n", i, target_sbc, new_sbc); result = PIGLIT_FAIL; } if (check_sbc != new_sbc) { fprintf(stderr, "iteration %u: GetSyncValues " "returned SBC %"PRId64" but Wait returned " "%"PRId64"\n", i, check_sbc, new_sbc); result = PIGLIT_FAIL; } if (new_msc > last_msc) { int64_t delta_msc = new_msc - last_msc; update_stats(&msc_ust_duration_stats, (new_ust - last_ust) / delta_msc); if (last_timestamp >= 0) { if (new_timestamp < 0) { fprintf(stderr, "no monotonic clock\n"); piglit_merge_result(&result, PIGLIT_WARN); } else { update_stats( &msc_wallclock_duration_stats, (new_timestamp - last_timestamp) / delta_msc); } } } expected_msc = target_msc; if (!target_msc) { /* If there is a divisor, the expected MSC is the * next MSC after last_msc such that * MSC % divisor == remainder */ int64_t last_remainder = last_msc % divisor; expected_msc = last_msc - last_remainder + msc_remainder; if (expected_msc <= last_msc) expected_msc += divisor; } if (new_msc < expected_msc) { fprintf(stderr, "iteration %u woke up %"PRId64 " MSCs early\n", i, expected_msc - new_msc); result = PIGLIT_FAIL; } if (new_msc > expected_msc) { fprintf(stderr, "iteration %u woke up %"PRId64 " MSCs later than expected\n", i, new_msc - expected_msc); piglit_merge_result(&result, PIGLIT_WARN); } if (new_msc % divisor != msc_remainder) { fprintf(stderr, "iteration %u woke up at wrong MSC" " remainder %"PRId64", not requested remainder" " %"PRId64"\n", i, new_msc % divisor, msc_remainder); result = PIGLIT_FAIL; } last_ust = new_ust; last_msc = new_msc; last_sbc = new_sbc; last_timestamp = new_timestamp; } if (msc_ust_duration_stats.n < 2) { fprintf(stderr, "Not enough UST timing samples\n"); piglit_merge_result(&result, PIGLIT_WARN); } else if (expected_msc_wallclock_duration > 0.0) { double apparent_ust_rate = msc_ust_duration_stats.mean / expected_msc_wallclock_duration; if (get_stddev(&msc_ust_duration_stats) / apparent_ust_rate > 100) { fprintf(stderr, "UST duration per MSC is surprisingly" " variable (stddev %f USTs), but then it only" " has to be monotonic\n", get_stddev(&msc_ust_duration_stats)); piglit_merge_result(&result, PIGLIT_WARN); } } if (msc_wallclock_duration_stats.n < 2) { fprintf(stderr, "Not enough wallclock timing samples\n"); piglit_merge_result(&result, PIGLIT_WARN); } else if (get_stddev(&msc_wallclock_duration_stats) > 1000) { fprintf(stderr, "Wallclock time between MSCs has stddev > 1ms" " (%fus), driver is probably not syncing to" " vblank\n", get_stddev(&msc_wallclock_duration_stats)); result = PIGLIT_FAIL; } else if (expected_msc_wallclock_duration > 0.0) { if (fabs(expected_msc_wallclock_duration - msc_wallclock_duration_stats.mean) > 50) { fprintf(stderr, "Wallclock time between MSCs %fus" " does not match glXGetMscRateOML %fus\n", msc_wallclock_duration_stats.mean, expected_msc_wallclock_duration); result = PIGLIT_FAIL; } } return result; }
enum piglit_result piglit_cl_test(const int argc, const char** argv, const struct piglit_cl_api_test_config* config, const struct piglit_cl_api_test_env* env) { #if defined(CL_VERSION_1_2) enum piglit_result result = PIGLIT_PASS; int i; cl_program_binary_type* binary_type; cl_program compiled_programs[2]; cl_program function_prog; cl_program kernel_prog; cl_program linked_prog; /* Create compiled program */ function_prog = compile_program(env->context->cl_ctx, env->context->num_devices, env->context->device_ids, 1, &strings[0], "function program"); kernel_prog = compile_program(env->context->cl_ctx, env->context->num_devices, env->context->device_ids, 2, &strings[1], "kernel program"); if (!function_prog || !kernel_prog) { clReleaseProgram(function_prog); clReleaseProgram(kernel_prog); return PIGLIT_FAIL; } compiled_programs[0] = function_prog; compiled_programs[1] = kernel_prog; /*** Normal usage ***/ test(env->context->cl_ctx, env->context->num_devices, env->context->device_ids, "-create-library", 1, compiled_programs, NULL, NULL, &linked_prog, CL_SUCCESS, &result, "Link program as library"); for(i = 0; i < env->context->num_devices; ++i) { binary_type = piglit_cl_get_program_build_info(linked_prog, env->context->device_ids[i], CL_PROGRAM_BINARY_TYPE); if (*binary_type != CL_PROGRAM_BINARY_TYPE_LIBRARY) { piglit_merge_result(&result, PIGLIT_FAIL); fprintf(stderr, "Failed: binary is not of type CL_PROGRAM_BINARY_TYPE_LIBRARY.\n"); } free(binary_type); } clReleaseProgram(linked_prog); test(env->context->cl_ctx, env->context->num_devices, env->context->device_ids, "", 2, compiled_programs, NULL, NULL, &linked_prog, CL_SUCCESS, &result, "Link program as executable"); for(i = 0; i < env->context->num_devices; ++i) { binary_type = piglit_cl_get_program_build_info(linked_prog, env->context->device_ids[i], CL_PROGRAM_BINARY_TYPE); if (*binary_type != CL_PROGRAM_BINARY_TYPE_EXECUTABLE) { piglit_merge_result(&result, PIGLIT_FAIL); fprintf(stderr, "Failed: binary is not of type CL_PROGRAM_BINARY_TYPE_EXECUTABLE.\n"); } free(binary_type); } /*** Errors ***/ /* * CL_INVALID_VALUE if device_list is NULL and num_devices is greater than * zero, or if device_list is not NULL and num_devices is zero */ test(env->context->cl_ctx, env->context->num_devices, NULL, "", 2, compiled_programs, NULL, NULL, NULL, CL_INVALID_VALUE, &result, "Trigger CL_INVALID_VALUE if device_list is NULL and num_devices is greater than zero"); test(env->context->cl_ctx, 0, env->context->device_ids, "", 2, compiled_programs, NULL, NULL, NULL, CL_INVALID_VALUE, &result, "Trigger CL_INVALID_VALUE if device_list is not NULL and num_devices is zero"); /* * CL_INVALID_VALUE if num_input_programs is zero and input_programs is NULL * or if num_input_programs is zero and input_programs is not NULL * or if num_input_programs is not zero and input_programs is NULL */ test(env->context->cl_ctx, env->context->num_devices, env->context->device_ids, "", 0, NULL, NULL, NULL, NULL, CL_INVALID_VALUE, &result, "Trigger CL_INVALID_VALUE if num_input_programs is zero and input_programs is NULL"); test(env->context->cl_ctx, env->context->num_devices, env->context->device_ids, "", 0, compiled_programs, NULL, NULL, NULL, CL_INVALID_VALUE, &result, "Trigger CL_INVALID_VALUE if num_input_programs is zero and input_programs is not NULL"); test(env->context->cl_ctx, env->context->num_devices, env->context->device_ids, "", 2, NULL, NULL, NULL, NULL, CL_INVALID_VALUE, &result, "Trigger CL_INVALID_VALUE if num_input_programs is not zero and input_programs is NULL"); /* * CL_INVALID_PROGRAM if programs specified in input_programs are not valid program objects */ /* * CL_INVALID_VALUE if pfn_notify is NULL but user_data is not NULL. */ test(env->context->cl_ctx, env->context->num_devices, env->context->device_ids, "", 2, compiled_programs, NULL, &i, NULL, CL_INVALID_VALUE, &result, "Trigger CL_INVALID_VALUE if pfn_notify is NULL but user_data is not NULL"); /* * CL_INVALID_DEVICE if OpenCL devices listed in device_list are not in the * list of devices associated with context */ /* * CL_INVALID_LINKER_OPTIONS if the linker options specified by options are * invalid */ test(env->context->cl_ctx, env->context->num_devices, env->context->device_ids, "-invalid- --link-- options", 2, compiled_programs, NULL, NULL, NULL, CL_INVALID_LINKER_OPTIONS, &result, "Trigger CL_INVALID_LINKER_OPTIONS if the linker options specified by options are invalid"); /* * CL_INVALID_OPERATION if the compilation or build of a program executable * for any of the devices listed in device_list by a previous call to * clCompileProgram or clBuildProgram for program has not completed */ /* * CL_INVALID_OPERATION if the rules for devices containing compiled binaries * or libraries as described in input_programs argument above are not followed */ compiled_programs[0] = linked_prog; test(env->context->cl_ctx, env->context->num_devices, env->context->device_ids, "", 2, compiled_programs, NULL, NULL, NULL, CL_INVALID_OPERATION, &result, "Trigger CL_INVALID_OPERATION if the rules for devices containing compiled binaries or libraries as described in input_programs argument above are not followed"); /* * CL_LINKER_NOT_AVAILABLE if a linker is not available * i.e. CL_DEVICE_LINKER_AVAILABLE specified in the table of allowed values * for param_name for clGetDeviceInfo is set to CL_FALSE. */ for(i = 0; i < env->context->num_devices; ++i) { cl_bool* linker_available = piglit_cl_get_device_info(env->context->device_ids[i], CL_DEVICE_LINKER_AVAILABLE); if(!(*linker_available)) { test(env->context->cl_ctx, env->context->num_devices, env->context->device_ids, "", 2, compiled_programs, NULL, NULL, NULL, CL_LINKER_NOT_AVAILABLE, &result, "Trigger CL_LINKER_NOT_AVAILABLE if a linker is not available"); } free(linker_available); } /* Release programs */ clReleaseProgram(function_prog); clReleaseProgram(kernel_prog); clReleaseProgram(linked_prog); /* * CL_LINK_PROGRAM_FAILURE if there is a failure to link the compiled binaries * and/or libraries. */ function_prog = compile_program(env->context->cl_ctx, env->context->num_devices, env->context->device_ids, 1, &strings[0], "2nd function program"); kernel_prog = compile_program(env->context->cl_ctx, env->context->num_devices, env->context->device_ids, 2, &strings[2], "2nd kernel program"); if (!function_prog || !kernel_prog) { result = PIGLIT_FAIL; } else { compiled_programs[0] = function_prog; compiled_programs[1] = kernel_prog; test(env->context->cl_ctx, env->context->num_devices, env->context->device_ids, "", 2, compiled_programs, NULL, NULL, NULL, CL_LINK_PROGRAM_FAILURE, &result, "Trigger CL_LINK_PROGRAM_FAILURE if there is a failure to link the compiled binaries and/or libraries"); } /* Release programs */ clReleaseProgram(function_prog); clReleaseProgram(kernel_prog); return result; #else return PIGLIT_SKIP; #endif }
/* Run the test(s) */ int piglit_cl_framework_run(int argc, char** argv) { enum piglit_result result = PIGLIT_SKIP; int version = 0; cl_platform_id platform_id = NULL; cl_device_id device_id = NULL; /* Get test configuration */ struct piglit_cl_test_config_header *config = piglit_cl_get_test_config(argc, (const char**)argv, &PIGLIT_CL_DEFAULT_TEST_CONFIG_HEADER); /* Check that config is valid */ // run_per_platform, run_per_device if(config->run_per_platform && config->run_per_device) { fprintf(stderr, "Invalid configuration, only one of run_per_platform and run_per_device can be true.\n"); piglit_report_result(PIGLIT_WARN); } /* Init */ if(config->init_func != NULL) { config->init_func(argc, (const char**)argv, config); } /* Print test name and file */ printf("## Test: %s (%s) ##\n\n", config->name != NULL ? config->name : "", config->_filename); /* Get version to test against */ version = piglit_cl_get_version_arg(argc, (const char **)argv); if(version > 0) { if(version > PIGLIT_CL_VERSION) { printf("Piglit was compiled with lower OpenCL version (%d.%d) than version argument: %d.%d.\n", PIGLIT_CL_VERSION/10, PIGLIT_CL_VERSION%10, version/10, version%10); piglit_report_result(PIGLIT_SKIP); } } else { /* * If version was not provided on the command line, set it to * the version against which Piglit was compiled (PIGLIT_CL_VERSION) */ version = PIGLIT_CL_VERSION; } /* Run the actual test */ if(!(config->run_per_platform || config->run_per_device)) { print_test_info(config, version, NULL, NULL); result = config->_test_run(argc, (const char**)argv, (void*)config, version, NULL, NULL); } else { /* Run tests per platform or device */ int i; regex_t platform_regex; regex_t device_regex; bool platform_defined; unsigned int num_platforms; cl_platform_id* platform_ids; /* Create regexes */ if( config->platform_regex != NULL && regcomp(&platform_regex, config->platform_regex, REG_EXTENDED | REG_NEWLINE)) { fprintf(stderr, "Regex to filter platforms is invalid, ignoring it.\n"); regcomp(&platform_regex, "", REG_EXTENDED | REG_NEWLINE); piglit_merge_result(&result, PIGLIT_WARN); } if( config->device_regex != NULL && regcomp(&device_regex, config->device_regex, REG_EXTENDED | REG_NEWLINE)) { fprintf(stderr, "Regex to filter devices is invalid, ignoring it.\n"); regcomp(&device_regex, "", REG_EXTENDED | REG_NEWLINE); piglit_merge_result(&result, PIGLIT_WARN); } /* check for command-line/environment platform */ platform_defined = piglit_cl_get_platform_arg(argc, (const char**)argv, &platform_id); /* generate platforms list */ if(platform_defined) { /* use platform defined by command-line/environment */ num_platforms = 1; platform_ids = malloc(sizeof(cl_platform_id)); platform_ids[0] = platform_id; } else { /* use all available platforms */ num_platforms = piglit_cl_get_platform_ids(&platform_ids); } /* execute test for each platform in platforms list */ for(i = 0; i < num_platforms; i++) { int final_version = version; int platform_version; platform_id = platform_ids[i]; /* Filter platform */ if(config->platform_regex != NULL) { char* platform_name; platform_name = piglit_cl_get_platform_info(platform_id, CL_PLATFORM_NAME); if(regexec(&platform_regex, platform_name, 0, NULL, 0)) { printf("\n# Skipping platform %s because it does not match platform_regex.\n\n", platform_name); free(platform_name); continue; } free(platform_name); } /* Check platform extensions */ if(!check_platform_extensions(platform_id, config->require_platform_extensions)) { continue; } /* Get platform version */ platform_version = piglit_cl_get_platform_version(platform_id); if(config->run_per_platform) { /* Check platform version */ if(platform_version < final_version) { printf("# Platform supporting only version %d.%d. Running test on that version.\n", platform_version/10, platform_version%10); final_version = platform_version; } /* run test on platform */ print_test_info(config, final_version, platform_id, NULL); piglit_merge_result(&result, config->_test_run(argc, (const char**)argv, (void*)config, final_version, platform_id, NULL)); } else { //config->run_per_device int j; bool device_defined; unsigned int num_devices; cl_device_id* device_ids; /* check for command-line/environment device */ device_defined = piglit_cl_get_device_arg(argc, (const char**)argv, platform_id, &device_id); /* generate devices list */ if(device_defined) { /* use device defined by command-line/environment */ num_devices = 1; device_ids = malloc(sizeof(cl_device_id)); device_ids[0] = device_id; } else { /* use all available devices */ num_devices = piglit_cl_get_device_ids(platform_id, CL_DEVICE_TYPE_ALL, &device_ids); } /* run tests per each device */ for(j = 0; j < num_devices; j++) { int device_version; device_id = device_ids[j]; /* Filter device */ if(config->device_regex != NULL) { char* device_name; device_name = piglit_cl_get_device_info(device_id, CL_DEVICE_NAME); if(regexec(&device_regex, device_name, 0, NULL, 0)) { printf("\n# Skipping device %s because it does not match device_regex.\n\n", device_name); free(device_name); continue; } free(device_name); } /* Check device extensions */ if(!check_device_extensions(device_id, config->require_device_extensions)) { continue; } /* Check platform version */ if(platform_version < final_version) { printf("# Platform supporting only version %d.%d. Running test on that version.\n", platform_version/10, platform_version%10); final_version = platform_version; } /* Check device version */ device_version = piglit_cl_get_device_version(device_id); if(device_version < final_version) { printf("# Device supporting only version %d.%d. Running test on that version.\n", device_version/10, device_version%10); final_version = device_version; } print_test_info(config, version, platform_id, device_id); piglit_merge_result(&result, config->_test_run(argc, (const char**)argv, (void*)config, final_version, platform_id, device_id)); } free(device_ids); } } if(config->platform_regex != NULL) { regfree(&platform_regex); } if(config->device_regex != NULL) { regfree(&device_regex); } free(platform_ids); } /* Clean */ if(config->clean_func != NULL) { config->clean_func(argc, (const char**)argv, config); } /* Report merged result */ printf("# Result:\n"); piglit_report_result(result); /* UNREACHED */ return 1; }
void piglit_init(int argc, char **argv) { GLuint fbo; static const char *vs_source = "#version 130\n" "void main()\n" "{\n" " gl_Position = gl_Vertex;\n" "}\n"; static const char *fs_source = "#version 130\n" "uniform uvec4 color;\n" "out uvec4 result;\n" "void main()\n" "{\n" " result = color;\n" "}\n"; GLuint fs, vs, prog; int f, i; enum piglit_result result = PIGLIT_SKIP; const struct format_info *test_formats = formats; int num_test_formats = ARRAY_SIZE(formats); for (i = 1; i < argc; i++) { if (strcmp(argv[i], "GL_ARB_texture_rg") == 0) { piglit_require_extension(argv[i]); test_formats = rg_formats; num_test_formats = ARRAY_SIZE(rg_formats); } else if (strcmp(argv[i], "GL_ARB_texture_rgb10_a2ui") == 0) { piglit_require_extension(argv[i]); test_formats = rgb10_formats; num_test_formats = ARRAY_SIZE(rgb10_formats); } else { usage(); exit(1); } } piglit_require_extension("GL_EXT_texture_integer"); piglit_require_GLSL_version(130); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source); prog = piglit_link_simple_program(vs, fs); if (!prog || !fs || !vs) piglit_report_result(PIGLIT_FAIL); glUseProgram(prog); color_loc = glGetUniformLocation(prog, "color"); glUniform4uiv(color_loc, 1, color); glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); /* Turn on all the knobs (except multisample alpha, which * we'll leave to an EXT_framebuffer_multisample test) that * are supposed to be ignored. */ glEnable(GL_BLEND); glBlendFunc(GL_ZERO, GL_ZERO); glEnable(GL_DITHER); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_NEVER, 1); for (f = 0; f < num_test_formats; f++) piglit_merge_result(&result, test_format(&test_formats[f])); glBindFramebuffer(GL_FRAMEBUFFER, 0); glDeleteFramebuffers(1, &fbo); piglit_report_result(result); }
PIGLIT_CL_API_TEST_CONFIG_END enum piglit_result piglit_cl_test(const int argc, const char** argv, const struct piglit_cl_api_test_config* config, const struct piglit_cl_api_test_env* env) { enum piglit_result result = PIGLIT_PASS; int i; cl_int errNo; cl_command_queue command_queue = env->context->command_queues[0]; size_t param_value_size; void* param_value; int num_command_queue_infos = PIGLIT_CL_ENUM_NUM(cl_command_queue_info, env->version); const cl_command_queue_info *command_queue_infos = PIGLIT_CL_ENUM_ARRAY(cl_command_queue_info); /*** Normal usage ***/ for(i = 0; i < num_command_queue_infos; i++) { printf("%s ", piglit_cl_get_enum_name(command_queue_infos[i])); errNo = clGetCommandQueueInfo(command_queue, command_queue_infos[i], 0, NULL, ¶m_value_size); if(!piglit_cl_check_error(errNo, CL_SUCCESS)) { fprintf(stderr, "Failed (error code: %s): Get size of %s.\n", piglit_cl_get_error_name(errNo), piglit_cl_get_enum_name(command_queue_infos[i])); piglit_merge_result(&result, PIGLIT_FAIL); continue; } param_value = malloc(param_value_size); errNo = clGetCommandQueueInfo(command_queue, command_queue_infos[i], param_value_size, param_value, NULL); if(!piglit_cl_check_error(errNo, CL_SUCCESS)) { fprintf(stderr, "Failed (error code: %s): Get value of %s.\n", piglit_cl_get_error_name(errNo), piglit_cl_get_enum_name(command_queue_infos[i])); piglit_merge_result(&result, PIGLIT_FAIL); } //TODO: output returned values printf("\n"); free(param_value); } /*** Errors ***/ /* * CL_INVALID_VALUE if param_name is not one of the supported * values or if size in bytes specified by param_value_size is * less than size of return type and param_value is not a NULL * value. */ errNo = clGetCommandQueueInfo(command_queue, CL_PLATFORM_NAME, 0, NULL, ¶m_value_size); if(!piglit_cl_check_error(errNo, CL_INVALID_VALUE)) { fprintf(stderr, "Failed (error code: %s): Trigger CL_INVALID_VALUE if param_name is not one of the supported values.\n", piglit_cl_get_error_name(errNo)); piglit_merge_result(&result, PIGLIT_FAIL); } errNo = clGetCommandQueueInfo(command_queue, CL_QUEUE_REFERENCE_COUNT, 1, param_value, NULL); if(!piglit_cl_check_error(errNo, CL_INVALID_VALUE)) { fprintf(stderr, "Failed (error code: %s): Trigger CL_INVALID_VALUE if size in bytes specified by param_value is less than size of return type and param_value is not a NULL value.\n", piglit_cl_get_error_name(errNo)); piglit_merge_result(&result, PIGLIT_FAIL); } /* * CL_INVALID_COMMAND_QUEUE if command_queue is not a valid command queue. */ errNo = clGetCommandQueueInfo(NULL, CL_QUEUE_CONTEXT, 0, NULL, ¶m_value_size); if(!piglit_cl_check_error(errNo, CL_INVALID_COMMAND_QUEUE)) { fprintf(stderr, "Failed (error code: %s): Trigger CL_INVALID_COMMAND_QUEUE if command_queue is not a valid command queue.\n", piglit_cl_get_error_name(errNo)); piglit_merge_result(&result, PIGLIT_FAIL); } return result; }
enum piglit_result piglit_cl_test(const int argc, const char** argv, const struct piglit_cl_api_test_config* config, const struct piglit_cl_api_test_env* env) { enum piglit_result result = PIGLIT_PASS; int i; int mask; cl_int errNo; cl_context cl_ctx; cl_command_queue command_queue; cl_uint num_devices; cl_device_id* devices; cl_command_queue_properties mixed_command_queue_properties[4] = {CL_QUEUE_PROPERTIES, 0, 0, 0}; cl_context_properties context_properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)env->platform_id, 0 }; int num_command_queue_properties = PIGLIT_CL_ENUM_NUM(cl_command_queue_properties, env->version); const cl_command_queue_properties* command_queue_properties = PIGLIT_CL_ENUM_ARRAY(cl_command_queue_properties); /*** Normal usage ***/ /* create context */ cl_ctx = clCreateContext(context_properties, 1, &env->device_id, NULL, NULL, &errNo); if(errNo == CL_DEVICE_NOT_FOUND) { fprintf(stderr, "No available devices.\n"); return PIGLIT_SKIP; } if(!piglit_cl_check_error(errNo, CL_SUCCESS)) { fprintf(stderr, "Failed (error code: %s): Create context.\n", piglit_cl_get_error_name(errNo)); return PIGLIT_FAIL; } /* * For each command queue properties mix. * There are 2^(num_command_queue_properties)-1 possible options. */ for(mask = 0; mask < (1 << num_command_queue_properties); mask++) { mixed_command_queue_properties[1] = get_mixed_command_queue_properties(mask, command_queue_properties); if (properties_forbidden(mixed_command_queue_properties[1], env)) continue; #if defined CL_VERSION_2_0 if (env->version >= 20) { command_queue = clCreateCommandQueueWithProperties( cl_ctx, env->device_id, mixed_command_queue_properties, &errNo); } else #endif //CL_VERSION_2_0 { command_queue = clCreateCommandQueue(cl_ctx, env->device_id, mixed_command_queue_properties[1], &errNo); } if(errNo != CL_SUCCESS && errNo != CL_INVALID_QUEUE_PROPERTIES) { piglit_cl_check_error(errNo, CL_SUCCESS); fprintf(stderr, "Failed (error code: %s): Create command queue using 0x%X as command queue properties.\n", piglit_cl_get_error_name(errNo), (unsigned int)mixed_command_queue_properties[1]); piglit_merge_result(&result, PIGLIT_FAIL); } clReleaseCommandQueue(command_queue); } /*** Errors ***/ /* * CL_INVALID_CONTEXT if context is not a valid context. */ clCreateCommandQueue(NULL, env->device_id, 0, &errNo); if(!piglit_cl_check_error(errNo, CL_INVALID_CONTEXT)) { fprintf(stderr, "Failed (error code: %s): Trigger CL_INVALID_CONTEXT if contest is not a valid context.\n", piglit_cl_get_error_name(errNo)); piglit_merge_result(&result, PIGLIT_FAIL); } /* * CL_INVALID_DEVICE if device is not a valid device or is * not associated with context. */ clCreateCommandQueue(cl_ctx, NULL, 0, &errNo); if(!piglit_cl_check_error(errNo, CL_INVALID_DEVICE)) { fprintf(stderr, "Failed (error code: %s): Trigger CL_INVALID_DEVICE if device is not a valid device.\n", piglit_cl_get_error_name(errNo)); piglit_merge_result(&result, PIGLIT_FAIL); } num_devices = piglit_cl_get_device_ids(env->platform_id, CL_DEVICE_TYPE_ALL, &devices); for(i = 0; i < num_devices; i++) { if(devices[i] != env->device_id) { clCreateCommandQueue(cl_ctx, devices[i], 0, &errNo); if(!piglit_cl_check_error(errNo, CL_INVALID_DEVICE)) { fprintf(stderr, "Failed (error code: %s): Trigger CL_INVALID_DEVICE if device that is not associated with context.\n", piglit_cl_get_error_name(errNo)); piglit_merge_result(&result, PIGLIT_FAIL); } } } free(devices); /* * CL_INVALID_VALUE if values specified in properties are not valid. */ clCreateCommandQueue(cl_ctx, env->device_id, 0XFFFFFFFF, &errNo); if(!piglit_cl_check_error(errNo, CL_INVALID_VALUE)) { fprintf(stderr, "Failed (error code: %s): Trigger CL_INVALID_VALUE if values specified in properties are not valid.\n", piglit_cl_get_error_name(errNo)); piglit_merge_result(&result, PIGLIT_FAIL); } /* * CL_INVALID_QUEUE_PROPERTIES if values specified in properties * are valid but are not supported by the device. * * Note: already tested in 'normal usage' section */ clReleaseContext(cl_ctx); return result; }
enum piglit_result piglit_cl_test(const int argc, const char **argv, const struct piglit_cl_api_test_config* config, const struct piglit_cl_api_test_env* env) { #if defined(CL_VERSION_1_2) enum piglit_result result = PIGLIT_PASS; cl_int err; #define IMG_WIDTH 4 #define IMG_HEIGHT 4 #define IMG_DATA_SIZE 4 #define IMG_BUFFER_SIZE IMG_WIDTH * IMG_HEIGHT * IMG_DATA_SIZE unsigned char img_buf[IMG_BUFFER_SIZE] = {0}; unsigned char dst_buf[IMG_BUFFER_SIZE] = {0}; unsigned char exp_buf[IMG_BUFFER_SIZE] = {0}; int pattern[4] = {129, 33, 77, 255}; size_t origin[3] = {0, 0, 0}; size_t region[3] = {2, 2, 1}; size_t tmp; cl_event event; cl_mem image; cl_image_format img_format; cl_image_desc img_desc = {0}; cl_command_queue queue = env->context->command_queues[0]; int i; cl_bool *image_support = piglit_cl_get_device_info(env->context->device_ids[0], CL_DEVICE_IMAGE_SUPPORT); if (!*image_support) { fprintf(stderr, "No image support\n"); free(image_support); return PIGLIT_SKIP; } img_format.image_channel_order = CL_RGBA; img_format.image_channel_data_type = CL_UNSIGNED_INT8; img_desc.image_type = CL_MEM_OBJECT_IMAGE2D; img_desc.image_width = IMG_WIDTH; img_desc.image_height = IMG_HEIGHT; img_desc.buffer = NULL; /*** Normal usage ***/ image = clCreateImage(env->context->cl_ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &img_format, &img_desc, &img_buf, &err); if(!piglit_cl_check_error(err, CL_SUCCESS)) { fprintf(stderr, "Failed (error code: %s): Creating an image\n", piglit_cl_get_error_name(err)); return PIGLIT_FAIL; } if (!test(queue, image, pattern, origin, region, 0, NULL, NULL, CL_SUCCESS, &result, "Enqueuing the image to be filled")) { return PIGLIT_FAIL; } region[0] = IMG_WIDTH; region[1] = IMG_HEIGHT; err = clEnqueueReadImage(queue, image, 1, origin, region, 0, 0, dst_buf, 0, NULL, NULL); if(!piglit_cl_check_error(err, CL_SUCCESS)) { fprintf(stderr, "Failed (error code: %s): Reading image\n", piglit_cl_get_error_name(err)); return PIGLIT_FAIL; } /* * fill the host buffer with the pattern * for exemple : pattern == 1234 * * 12341234abcdabcd * 12341234abcdabcd * abcdabcdabcdabcd * abcdabcdabcdabcd */ exp_buf[0] = pattern[0]; exp_buf[1] = pattern[1]; exp_buf[2] = pattern[2]; exp_buf[3] = pattern[3]; memcpy(exp_buf + (IMG_DATA_SIZE * 1), exp_buf, IMG_DATA_SIZE); memcpy(exp_buf + (IMG_DATA_SIZE * 4), exp_buf, IMG_DATA_SIZE); memcpy(exp_buf + (IMG_DATA_SIZE * 5), exp_buf, IMG_DATA_SIZE); for (i = 0; i < sizeof(dst_buf) / sizeof(dst_buf[0]); ++i) { if (!piglit_cl_probe_integer(dst_buf[i], exp_buf[i], 0)) { fprintf(stderr, "Error at %d: got %d, expected %d\n", i, dst_buf[i], exp_buf[i]); return PIGLIT_FAIL; } } /*** Errors ***/ /* * CL_INVALID_COMMAND_QUEUE if command_queue is not a valid command-queue. */ test(NULL, image, pattern, origin, region, 0, NULL, NULL, CL_INVALID_COMMAND_QUEUE, &result, "CL_INVALID_COMMAND_QUEUE if command_queue is not a valid command-queue"); /* * CL_INVALID_CONTEXT if the context associated with command_queue and * image are not the same or if the context associated with command_queue * and events in event_wait_list are not the same. */ { piglit_cl_context context; cl_int err; context = piglit_cl_create_context(env->platform_id, env->context->device_ids, 1); if (context) { event = clCreateUserEvent(context->cl_ctx, &err); if (err == CL_SUCCESS) { err = clSetUserEventStatus(event, CL_COMPLETE); if (err == CL_SUCCESS) { test(context->command_queues[0], image, pattern, origin, region, 0, NULL, NULL, CL_INVALID_CONTEXT, &result, "CL_INVALID_CONTEXT if the context associated with command_queue and image are not the same"); test(queue, image, pattern, origin, region, 1, &event, NULL, CL_INVALID_CONTEXT, &result, "CL_INVALID_CONTEXT if the context associated with command_queue and events in event_wait_list are not the same"); } else { fprintf(stderr, "Could not set event status.\n"); piglit_merge_result(&result, PIGLIT_WARN); } clReleaseEvent(event); } else { fprintf(stderr, "Could not create user event.\n"); piglit_merge_result(&result, PIGLIT_WARN); } piglit_cl_release_context(context); } else { fprintf(stderr, "Could not test triggering CL_INVALID_CONTEXT.\n"); piglit_merge_result(&result, PIGLIT_WARN); } } /* * CL_INVALID_MEM_OBJECT if image is not a valid buffer object. */ test(queue, NULL, pattern, origin, region, 0, NULL, NULL, CL_INVALID_MEM_OBJECT, &result, "CL_INVALID_MEM_OBJECT if image is not a valid buffer object"); /* * CL_INVALID_VALUE if fill_color is NULL. */ test(queue, image, NULL, origin, region, 0, NULL, NULL, CL_INVALID_VALUE, &result, "CL_INVALID_VALUE if fill_color is NULL"); /* * CL_INVALID_VALUE if the region being written specified by origin and * region is out of bounds or if ptr is a NULL value. */ tmp = origin[0]; origin[0] = IMG_WIDTH + 1; test(queue, image, pattern, origin, region, 0, NULL, NULL, CL_INVALID_VALUE, &result, "CL_INVALID_VALUE if the region being written specified by origin and region is out of bounds (origin)"); origin[0] = tmp; tmp = region[0]; region[0] = IMG_WIDTH + 1; test(queue, image, pattern, origin, region, 0, NULL, NULL, CL_INVALID_VALUE, &result, "CL_INVALID_VALUE if the region being written specified by origin and region is out of bounds (region)"); region[0] = tmp; test(queue, image, pattern, NULL, region, 0, NULL, NULL, CL_INVALID_VALUE, &result, "CL_INVALID_VALUE if ptr is a NULL value (origin)"); test(queue, image, pattern, origin, NULL, 0, NULL, NULL, CL_INVALID_VALUE, &result, "CL_INVALID_VALUE if ptr is a NULL value (region)"); /* * CL_INVALID_VALUE if values in origin and region do not follow rules * described in the argument description for origin and region. */ tmp = origin[2]; origin[2] = 1; test(queue, image, pattern, origin, region, 0, NULL, NULL, CL_INVALID_VALUE, &result, "CL_INVALID_VALUE if values in origin do not follow rules described in the argument description for origin"); origin[2] = tmp; tmp = region[2]; region[2] = 0; test(queue, image, pattern, origin, region, 0, NULL, NULL, CL_INVALID_VALUE, &result, "CL_INVALID_VALUE if values in region do not follow rules described in the argument description for region"); region[2] = tmp; /* * CL_INVALID_EVENT_WAIT_LIST if event_wait_list is NULL and * num_events_in_wait_list > 0, or event_wait_list is not NULL and * num_events_in_wait_list is 0, or if event objects in event_wait_list * are not valid events. */ event = NULL; test(queue, image, pattern, origin, region, 1, NULL, NULL, CL_INVALID_EVENT_WAIT_LIST, &result, "CL_INVALID_EVENT_WAIT_LIST if event_wait_list is NULL and num_events_in_wait_list > 0"); test(queue, image, pattern, origin, region, 0, &event, NULL, CL_INVALID_EVENT_WAIT_LIST, &result, "CL_INVALID_EVENT_WAIT_LIST if event_wait_list is not NULL and num_events_in_wait_list is 0"); test(queue, image, pattern, origin, region, 1, &event, NULL, CL_INVALID_EVENT_WAIT_LIST, &result, "CL_INVALID_EVENT_WAIT_LIST if event objects in event_wait_list are not valid events"); /* * CL_INVALID_IMAGE_SIZE if image dimensions (image width, height, specified * or compute row and/or slice pitch) for image are not supported by device * associated with queue. */ /* This is a per device test, clCreateImage would have failed before */ /* * CL_INVALID_IMAGE_FORMAT if image format (image channel order and data type) * for image are not supported by device associated with queue. */ /* This is a per device test, clCreateImage would have failed before */ free(image_support); clReleaseMemObject(image); return result; #else return PIGLIT_SKIP; #endif }
PIGLIT_CL_API_TEST_CONFIG_END static void test(cl_context_properties *properties, cl_uint num_devices, const cl_device_id *devices, void pfn_notify ( const char *errinfo, const void *private_info, size_t cb, void *user_data ), void *user_data, cl_int expected_error, enum piglit_result* result, const char* test_str) { cl_int errNo; cl_context cl_ctx; /* with errNo */ cl_ctx = clCreateContext(properties, num_devices, devices, pfn_notify, user_data, &errNo); if(!piglit_cl_check_error(errNo, expected_error)) { fprintf(stderr, "Failed (error code: %s): %s.\n", piglit_cl_get_error_name(errNo), test_str); piglit_merge_result(result, PIGLIT_FAIL); return; }; if(expected_error == CL_SUCCESS) { if(cl_ctx == NULL) { printf("Expecting non-NULL cl_context\n"); fprintf(stderr, "Failed (NULL value returned): %s.\n", test_str); piglit_merge_result(result, PIGLIT_FAIL); return; } clReleaseContext(cl_ctx); } else if(cl_ctx != NULL) { printf("Expecting NULL cl_context\n"); fprintf(stderr, "Failed (non-NULL value returned): %s.\n", test_str); piglit_merge_result(result, PIGLIT_FAIL); return; } /* without errNo */ cl_ctx = clCreateContext(properties, num_devices, devices, pfn_notify, user_data, NULL); if(expected_error == CL_SUCCESS) { if(cl_ctx == NULL) { printf("Expecting non-NULL cl_context\n"); fprintf(stderr, "Failed (NULL value returned): %s.\n", test_str); piglit_merge_result(result, PIGLIT_FAIL); return; } clReleaseContext(cl_ctx); } else if(cl_ctx != NULL) { printf("Expecting NULL cl_context\n"); fprintf(stderr, "Failed (non-NULL value returned): %s.\n", test_str); piglit_merge_result(result, PIGLIT_FAIL); return; } }
PIGLIT_CL_API_TEST_CONFIG_END enum piglit_result piglit_cl_test(const int argc, const char** argv, const struct piglit_cl_api_test_config* config, const struct piglit_cl_api_test_env* env) { enum piglit_result result = PIGLIT_PASS; int i; cl_int errNo; cl_uint num_platforms; cl_platform_id* platforms = NULL; /*** Normal usage ***/ /* get number of platforms */ errNo = clGetPlatformIDs(0, NULL, &num_platforms); if(!piglit_cl_check_error(errNo, CL_SUCCESS)) { piglit_cl_check_error(errNo, CL_SUCCESS); fprintf(stderr, "Failed (error code: %s): Get size of platform list.\n", piglit_cl_get_error_name(errNo)); piglit_merge_result(&result, PIGLIT_FAIL); } else { /* * Get platform list. * Try returning from 1 to num_platforms platforms. */ for(i = 1; i <= num_platforms; i++) { platforms = malloc(i * sizeof(cl_platform_id)); errNo = clGetPlatformIDs(i, platforms, NULL); if(!piglit_cl_check_error(errNo, CL_SUCCESS)) { fprintf(stderr, "Failed (error code: %s): Get platform list.\n", piglit_cl_get_error_name(errNo)); piglit_merge_result(&result, PIGLIT_FAIL); } free(platforms); } } /*** Errors ***/ /* * CL_INVALID_VALUE if num_entries is equal * to zero and platforms is not NULL, or if both num_platforms * and platforms are NULL. */ errNo = clGetPlatformIDs(0, platforms, NULL); if(!piglit_cl_check_error(errNo, CL_INVALID_VALUE)) { fprintf(stderr, "Failed (error code: %s): Trigger CL_INVALID_VALUE if num_entries is equeal to zero and platforms is not NULL.\n", piglit_cl_get_error_name(errNo)); piglit_merge_result(&result, PIGLIT_FAIL); } errNo = clGetPlatformIDs(100, NULL, NULL); if(!piglit_cl_check_error(errNo, CL_INVALID_VALUE)) { fprintf(stderr, "Failed (error code: %s): Trigger CL_INVALID_VALUE if both num_platforms and platforms are NULL.\n", piglit_cl_get_error_name(errNo)); piglit_merge_result(&result, PIGLIT_FAIL); } return result; }