You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
265 lines
8.4 KiB
265 lines
8.4 KiB
/******************************************************************
|
|
Copyright (c) 2016 The Khronos Group Inc. All Rights Reserved.
|
|
|
|
This code is protected by copyright laws and contains material proprietary to the Khronos Group, Inc.
|
|
This is UNPUBLISHED PROPRIETARY SOURCE CODE that may not be disclosed in whole or in part to
|
|
third parties, and may not be reproduced, republished, distributed, transmitted, displayed,
|
|
broadcast or otherwise exploited in any manner without the express prior written permission
|
|
of Khronos Group. The receipt or possession of this code does not convey any rights to reproduce,
|
|
disclose, or distribute its contents, or to manufacture, use, or sell anything that it may describe,
|
|
in whole or in part other than under the terms of the Khronos Adopters Agreement
|
|
or Khronos Conformance Test Source License Agreement as executed between Khronos and the recipient.
|
|
******************************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "procs.h"
|
|
#if !defined(_WIN32)
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <sstream>
|
|
|
|
#if defined(_WIN32)
|
|
const std::string slash = "\\";
|
|
#else
|
|
const std::string slash = "/";
|
|
#endif
|
|
|
|
const std::string spvExt = ".spv";
|
|
std::string gAddrWidth = "";
|
|
std::string spvBinariesPath = "spirv_bin";
|
|
std::string spvBinariesPathArg = "--spirv-binaries-path";
|
|
|
|
std::vector<unsigned char> readBinary(const char *file_name)
|
|
{
|
|
using namespace std;
|
|
|
|
ifstream file(file_name, ios::in | ios::binary | ios::ate);
|
|
|
|
std::vector<char> tmpBuffer(0);
|
|
|
|
if (file.is_open()) {
|
|
size_t size = file.tellg();
|
|
tmpBuffer.resize(size);
|
|
file.seekg(0, ios::beg);
|
|
file.read(&tmpBuffer[0], size);
|
|
file.close();
|
|
} else {
|
|
log_error("File %s not found\n", file_name);
|
|
}
|
|
|
|
std::vector<unsigned char> result(tmpBuffer.begin(), tmpBuffer.end());
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
std::vector<unsigned char> readSPIRV(const char *file_name)
|
|
{
|
|
std::string full_name_str = spvBinariesPath + slash + file_name + spvExt + gAddrWidth;
|
|
return readBinary(full_name_str.c_str());
|
|
}
|
|
|
|
test_definition *spirvTestsRegistry::getTestDefinitions()
|
|
{
|
|
return &testDefinitions[0];
|
|
}
|
|
|
|
size_t spirvTestsRegistry::getNumTests()
|
|
{
|
|
return testDefinitions.size();
|
|
}
|
|
|
|
void spirvTestsRegistry::addTestClass(baseTestClass *test, const char *testName,
|
|
Version version)
|
|
{
|
|
|
|
testClasses.push_back(test);
|
|
test_definition testDef;
|
|
testDef.func = test->getFunction();
|
|
testDef.name = testName;
|
|
testDef.min_version = version;
|
|
testDefinitions.push_back(testDef);
|
|
}
|
|
|
|
spirvTestsRegistry& spirvTestsRegistry::getInstance()
|
|
{
|
|
static spirvTestsRegistry instance;
|
|
return instance;
|
|
}
|
|
|
|
static int offline_get_program_with_il(clProgramWrapper &prog,
|
|
const cl_device_id deviceID,
|
|
const cl_context context,
|
|
const char *prog_name)
|
|
{
|
|
cl_int err = 0;
|
|
std::string outputTypeStr = "binary";
|
|
std::string defaultScript = std::string("..") + slash + std::string("spv_to_binary.py");
|
|
std::string outputFilename = spvBinariesPath + slash + std::string(prog_name);
|
|
std::string sourceFilename = outputFilename + spvExt;
|
|
|
|
std::string scriptArgs =
|
|
sourceFilename + " " +
|
|
outputFilename + " " +
|
|
gAddrWidth + " " +
|
|
outputTypeStr + " " +
|
|
"-cl-std=CL2.0";
|
|
|
|
std::string scriptToRunString = defaultScript + scriptArgs;
|
|
|
|
// execute script
|
|
log_info("Executing command: %s\n", scriptToRunString.c_str());
|
|
fflush(stdout);
|
|
int returnCode = system(scriptToRunString.c_str());
|
|
if (returnCode != 0) {
|
|
log_error("Command finished with error: 0x%x\n", returnCode);
|
|
return CL_COMPILE_PROGRAM_FAILURE;
|
|
}
|
|
|
|
// read output file
|
|
std::vector<unsigned char> buffer_vec = readBinary(outputFilename.c_str());
|
|
size_t file_bytes = buffer_vec.size();
|
|
if (file_bytes == 0) {
|
|
log_error("OfflinerCompiler: Failed to open binary file: %s", outputFilename.c_str());
|
|
return -1;
|
|
}
|
|
|
|
const unsigned char *buffer = &buffer_vec[0];
|
|
cl_int status = 0;
|
|
prog = clCreateProgramWithBinary(context, 1, &deviceID, &file_bytes, &buffer, &status, &err);
|
|
SPIRV_CHECK_ERROR((err || status), "Failed to create program with clCreateProgramWithBinary");
|
|
return err;
|
|
}
|
|
|
|
int get_program_with_il(clProgramWrapper &prog, const cl_device_id deviceID,
|
|
const cl_context context, const char *prog_name,
|
|
spec_const spec_const_def)
|
|
{
|
|
cl_int err = 0;
|
|
if (gCompilationMode == kBinary)
|
|
{
|
|
return offline_get_program_with_il(prog, deviceID, context, prog_name);
|
|
}
|
|
|
|
std::vector<unsigned char> buffer_vec = readSPIRV(prog_name);
|
|
|
|
int file_bytes = buffer_vec.size();
|
|
if (file_bytes == 0)
|
|
{
|
|
log_error("File %s not found\n", prog_name);
|
|
return -1;
|
|
}
|
|
|
|
unsigned char *buffer = &buffer_vec[0];
|
|
if (gCoreILProgram)
|
|
{
|
|
prog = clCreateProgramWithIL(context, buffer, file_bytes, &err);
|
|
SPIRV_CHECK_ERROR(
|
|
err, "Failed to create program with clCreateProgramWithIL");
|
|
|
|
if (spec_const_def.spec_value != NULL)
|
|
{
|
|
err = clSetProgramSpecializationConstant(
|
|
prog, spec_const_def.spec_id, spec_const_def.spec_size,
|
|
spec_const_def.spec_value);
|
|
SPIRV_CHECK_ERROR(
|
|
err, "Failed to run clSetProgramSpecializationConstant");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cl_platform_id platform;
|
|
err = clGetDeviceInfo(deviceID, CL_DEVICE_PLATFORM,
|
|
sizeof(cl_platform_id), &platform, NULL);
|
|
SPIRV_CHECK_ERROR(err,
|
|
"Failed to get platform info with clGetDeviceInfo");
|
|
clCreateProgramWithILKHR_fn clCreateProgramWithILKHR = NULL;
|
|
|
|
clCreateProgramWithILKHR = (clCreateProgramWithILKHR_fn)
|
|
clGetExtensionFunctionAddressForPlatform(
|
|
platform, "clCreateProgramWithILKHR");
|
|
if (clCreateProgramWithILKHR == NULL)
|
|
{
|
|
log_error(
|
|
"ERROR: clGetExtensionFunctionAddressForPlatform failed\n");
|
|
return -1;
|
|
}
|
|
prog = clCreateProgramWithILKHR(context, buffer, file_bytes, &err);
|
|
SPIRV_CHECK_ERROR(
|
|
err, "Failed to create program with clCreateProgramWithILKHR");
|
|
}
|
|
|
|
err = clBuildProgram(prog, 1, &deviceID, NULL, NULL, NULL);
|
|
SPIRV_CHECK_ERROR(err, "Failed to build program");
|
|
|
|
return err;
|
|
}
|
|
|
|
test_status InitCL(cl_device_id id)
|
|
{
|
|
test_status spirv_status;
|
|
bool force = true;
|
|
spirv_status = check_spirv_compilation_readiness(id);
|
|
if (spirv_status != TEST_PASS)
|
|
{
|
|
return spirv_status;
|
|
}
|
|
|
|
cl_uint address_bits;
|
|
cl_uint err = clGetDeviceInfo(id, CL_DEVICE_ADDRESS_BITS, sizeof(cl_uint),
|
|
&address_bits, NULL);
|
|
if (err != CL_SUCCESS)
|
|
{
|
|
log_error("clGetDeviceInfo failed to get address bits!");
|
|
return TEST_FAIL;
|
|
}
|
|
|
|
gAddrWidth = address_bits == 32 ? "32" : "64";
|
|
return TEST_PASS;
|
|
}
|
|
|
|
void printUsage() {
|
|
log_info("Reading SPIR-V files from default '%s' path.\n", spvBinariesPath.c_str());
|
|
log_info("In case you want to set other directory use '%s' argument.\n", spvBinariesPathArg.c_str());
|
|
}
|
|
|
|
int main(int argc, const char *argv[])
|
|
{
|
|
gReSeed = 1;
|
|
bool modifiedSpvBinariesPath = false;
|
|
for (int i = 0; i < argc; ++i) {
|
|
int argsRemoveNum = 0;
|
|
if (argv[i] == spvBinariesPathArg) {
|
|
if (i + 1 == argc) {
|
|
log_error("Missing value for '%s' argument.\n", spvBinariesPathArg.c_str());
|
|
return TEST_FAIL;
|
|
} else {
|
|
spvBinariesPath = std::string(argv[i + 1]);
|
|
argsRemoveNum += 2;
|
|
modifiedSpvBinariesPath = true;
|
|
}
|
|
}
|
|
|
|
if (argsRemoveNum > 0) {
|
|
for (int j = i; j < (argc - argsRemoveNum); ++j)
|
|
argv[j] = argv[j + argsRemoveNum];
|
|
|
|
argc -= argsRemoveNum;
|
|
--i;
|
|
}
|
|
}
|
|
if (modifiedSpvBinariesPath == false) {
|
|
printUsage();
|
|
}
|
|
|
|
return runTestHarnessWithCheck(
|
|
argc, argv, spirvTestsRegistry::getInstance().getNumTests(),
|
|
spirvTestsRegistry::getInstance().getTestDefinitions(), false, 0,
|
|
InitCL);
|
|
}
|