bd5105d7174f17c350566dc6080b147fc34e17c2
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / framework / vulkan / vkSpirVAsm.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan CTS Framework
3  * --------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and/or associated documentation files (the
9  * "Materials"), to deal in the Materials without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Materials, and to
12  * permit persons to whom the Materials are furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice(s) and this permission notice shall be
16  * included in all copies or substantial portions of the Materials.
17  *
18  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
25  *
26  *//*!
27  * \file
28  * \brief SPIR-V assembly to binary.
29  *//*--------------------------------------------------------------------*/
30
31 #include "vkSpirVAsm.hpp"
32 #include "vkSpirVProgram.hpp"
33 #include "deArrayUtil.hpp"
34 #include "deMemory.h"
35 #include "deClock.h"
36 #include "qpDebugOut.h"
37
38 #if defined(DEQP_HAVE_SPIRV_TOOLS)
39 #       include "libspirv/libspirv.h"
40 #endif
41
42 namespace vk
43 {
44
45 using std::string;
46 using std::vector;
47
48 #if defined(DEQP_HAVE_SPIRV_TOOLS)
49
50
51 void assembleSpirV (const SpirVAsmSource* program, std::vector<deUint8>* dst, SpirVProgramInfo* buildInfo)
52 {
53         spv_context context = spvContextCreate();
54
55         const std::string&      spvSource                       = program->program.str();
56         spv_binary                      binary                          = DE_NULL;
57         spv_diagnostic          diagnostic                      = DE_NULL;
58         const deUint64          compileStartTime        = deGetMicroseconds();
59         const spv_result_t      compileOk                       = spvTextToBinary(context, spvSource.c_str(), spvSource.size(), &binary, &diagnostic);
60
61         {
62                 buildInfo->source                       = program;
63                 buildInfo->infoLog                      = diagnostic? diagnostic->error : ""; // \todo [2015-07-13 pyry] Include debug log?
64                 buildInfo->compileTimeUs        = deGetMicroseconds() - compileStartTime;
65                 buildInfo->compileOk            = (compileOk == SPV_SUCCESS);
66         }
67
68         if (compileOk != SPV_SUCCESS)
69                 TCU_FAIL("Failed to compile shader");
70
71         dst->resize((int)binary->wordCount * sizeof(deUint32));
72 #if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
73         deMemcpy(&(*dst)[0], &binary->code[0], dst->size());
74 #else
75 #       error "Big-endian not supported"
76 #endif
77         spvBinaryDestroy(binary);
78         spvDiagnosticDestroy(diagnostic);
79         spvContextDestroy(context);
80         return;
81 }
82
83 bool validateSpirV (const std::vector<deUint8>& spirv, std::string* infoLog)
84 {
85         const size_t bytesPerWord = sizeof(uint32_t) / sizeof(deUint8);
86         DE_ASSERT(spirv.size() % bytesPerWord == 0);
87         std::vector<uint32_t> words(spirv.size() / bytesPerWord);
88         deMemcpy(words.data(), spirv.data(), spirv.size());
89         spv_const_binary_t      cbinary         = { words.data(), words.size() };
90         spv_diagnostic          diagnostic      = DE_NULL;
91         spv_context                     context         = spvContextCreate();
92         const spv_result_t      valid           = spvValidate(context, &cbinary, SPV_VALIDATE_ALL, &diagnostic);
93         if (diagnostic)
94                 *infoLog += diagnostic->error;
95         spvContextDestroy(context);
96         spvDiagnosticDestroy(diagnostic);
97         return valid == SPV_SUCCESS;
98 }
99
100 #else // defined(DEQP_HAVE_SPIRV_TOOLS)
101
102 void assembleSpirV (const SpirVAsmSource*, std::vector<deUint8>*, SpirVProgramInfo*)
103 {
104         TCU_THROW(NotSupportedError, "SPIR-V assembly not supported (DEQP_HAVE_SPIRV_TOOLS not defined)");
105 }
106
107 bool validateSpirV (const std::vector<deUint8>&, std::string*)
108 {
109         TCU_THROW(NotSupportedError, "SPIR-V validation not supported (DEQP_HAVE_SPIRV_TOOLS not defined)");
110 }
111
112 #endif
113
114 } // vk