blob: 04aed875c9064d599026d660c386c21227b6355b [file] [log] [blame]
/*-------------------------------------------------------------------------
* Vulkan CTS Framework
* --------------------
*
* Copyright (c) 2021 The Khronos Group Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*-------------------------------------------------------------------------*/
#include "vksServices.hpp"
#include "vksJson.hpp"
#include "vksCacheBuilder.hpp"
#include "vksStore.hpp"
#include <map>
#include <mutex>
#include <fstream>
#include <iostream>
#include "deUniquePtr.hpp"
#include "vkPrograms.hpp"
#include "vkPlatform.hpp"
#include "vkDeviceUtil.hpp"
#include "vktTestCase.hpp"
#include "tcuCommandLine.hpp"
#include "tcuPlatform.hpp"
#include "tcuTestContext.hpp"
#include "tcuResource.hpp"
#include "tcuTestLog.hpp"
tcu::Platform *createPlatform(void);
struct VkscServer
{
const vk::PlatformInterface &vkp;
vk::VkInstance instance;
const vk::InstanceInterface &vki;
vk::VkPhysicalDevice physicalDevice;
uint32_t queueIndex;
const vk::VkPhysicalDeviceFeatures2 &enabledFeatures;
};
VkscServer *createServerVKSC(const std::string &logFile);
std::unique_ptr<VkscServer> vkscServer;
namespace vksc_server
{
using namespace json;
Store ServiceStore;
bool LoadPhysicalFile(const string &path, vector<u8> &content)
{
std::ifstream file(path, std::ios::binary);
if (!file)
return false;
content.assign((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
return true;
}
bool StoreFile(const string &uniqueFilename, const vector<u8> &content)
{
return ServiceStore.Set(uniqueFilename, content);
}
bool GetFile(const string &path, vector<u8> &content, bool removeAfter)
{
return ServiceStore.Get(path, content, removeAfter) || LoadPhysicalFile(path, content);
}
bool AppendFile(const string &path, const vector<u8> &content, bool clear)
{
auto mode = clear ? std::ios::binary : std::ios::binary | std::ios::app;
std::ofstream file(path, mode);
if (!file)
return false;
std::copy(content.begin(), content.end(), std::ostream_iterator<u8>{file});
return true;
}
void CreateVulkanSCCache(const VulkanPipelineCacheInput &input, int caseFraction, vector<u8> &binary,
const CmdLineParams &cmdLineParams, const std::string &logFile)
{
if (!cmdLineParams.compilerPath.empty())
{
std::stringstream prefix;
if (caseFraction >= 0)
prefix << "sub_" << caseFraction << "_";
else
prefix << "";
binary = vksc_server::buildOfflinePipelineCache(
input, cmdLineParams.compilerPath, cmdLineParams.compilerDataDir, cmdLineParams.compilerArgs,
cmdLineParams.compilerPipelineCacheFile, cmdLineParams.compilerLogFile, prefix.str());
}
else
{
if (vkscServer.get() == DE_NULL)
vkscServer.reset(createServerVKSC(logFile));
binary = buildPipelineCache(input, vkscServer->vkp, vkscServer->instance, vkscServer->vki,
vkscServer->physicalDevice, vkscServer->queueIndex);
}
}
bool CompileShader(const SourceVariant &source, const string &commandLine, vector<u8> &binary)
{
glu::ShaderProgramInfo programInfo;
vk::SpirVProgramInfo programInfoSpirv;
tcu::CommandLine cmd(commandLine);
std::unique_ptr<vk::ProgramBinary> programBinary;
if (source.active == "glsl")
programBinary.reset(vk::buildProgram(source.glsl, &programInfo, cmd));
else if (source.active == "hlsl")
programBinary.reset(vk::buildProgram(source.hlsl, &programInfo, cmd));
else if (source.active == "spirv")
programBinary.reset(vk::assembleProgram(source.spirv, &programInfoSpirv, cmd));
else
return false;
if (!programBinary || programBinary->getBinary() == nullptr)
{
return false;
}
if (programBinary->getFormat() != vk::PROGRAM_FORMAT_SPIRV)
{
throw std::runtime_error("CompileShader supports only PROGRAM_FORMAT_SPIRV binary output");
}
binary.assign(programBinary->getBinary(), programBinary->getBinary() + programBinary->getSize());
return true;
}
} // namespace vksc_server
VkscServer *createServerVKSC(const std::string &logFile)
{
tcu::CommandLine cmdLine{"--deqp-vk-device-id=0"};
tcu::DirArchive archive{""};
tcu::TestLog log{logFile.c_str()};
log.supressLogging(true);
tcu::Platform *platform{createPlatform()};
#ifdef DE_PLATFORM_USE_LIBRARY_TYPE
vk::Library *library{platform->getVulkanPlatform().createLibrary(vk::Platform::LIBRARY_TYPE_VULKAN, DE_NULL)};
#else
vk::Library *library{platform->getVulkanPlatform().createLibrary(DE_NULL)};
#endif
tcu::TestContext *tcx = new tcu::TestContext{*platform, archive, log, cmdLine, nullptr};
vk::ResourceInterface *resource = new vk::ResourceInterfaceStandard{*tcx};
vk::BinaryCollection *collection = new vk::BinaryCollection{};
vkt::Context *context = new vkt::Context(*tcx, library->getPlatformInterface(), *collection,
de::SharedPtr<vk::ResourceInterface>{resource});
VkscServer *result = new VkscServer{library->getPlatformInterface(), context->getInstance(),
context->getInstanceInterface(), context->getPhysicalDevice(),
context->getUniversalQueueFamilyIndex(), context->getDeviceFeatures2()};
return result;
}