Clean up SPIR-V support code in framework
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / framework / vulkan / vkSpirVAsm.cpp
index 549de3d..e864c3d 100644 (file)
  * The above copyright notice(s) and this permission notice shall be
  * included in all copies or substantial portions of the Materials.
  *
- * The Materials are Confidential Information as defined by the
- * Khronos Membership Agreement until designated non-confidential by
- * Khronos, at which point this condition clause shall be removed.
- *
  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 
 #include "vkSpirVAsm.hpp"
 #include "vkSpirVProgram.hpp"
-#include "deArrayUtil.hpp"
-#include "deMemory.h"
 #include "deClock.h"
-#include "qpDebugOut.h"
 
-#if defined(DEQP_HAVE_SPIRV_TOOLS)
-#      include "deSingleton.h"
+#include <algorithm>
 
-#      include "libspirv/libspirv.h"
+#if defined(DEQP_HAVE_SPIRV_TOOLS)
+#      include "spirv-tools/libspirv.h"
 #endif
 
 namespace vk
@@ -53,46 +46,121 @@ using std::vector;
 
 #if defined(DEQP_HAVE_SPIRV_TOOLS)
 
-
-void assembleSpirV (const SpirVAsmSource* program, std::vector<deUint8>* dst, SpirVProgramInfo* buildInfo)
+bool assembleSpirV (const SpirVAsmSource* program, std::vector<deUint32>* dst, SpirVProgramInfo* buildInfo)
 {
-       spv_context context = spvContextCreate();
+       const spv_context       context         = spvContextCreate();
+       spv_binary                      binary          = DE_NULL;
+       spv_diagnostic          diagnostic      = DE_NULL;
 
-       const std::string&      spvSource                       = program->program.str();
-       spv_binary                      binary                          = DE_NULL;
-       spv_diagnostic          diagnostic                      = DE_NULL;
-       const deUint64          compileStartTime        = deGetMicroseconds();
-       const spv_result_t      compileOk                       = spvTextToBinary(context, spvSource.c_str(), spvSource.size(), &binary, &diagnostic);
+       if (!context)
+               throw std::bad_alloc();
 
+       try
        {
-               buildInfo->source                       = program;
+               const std::string&      spvSource                       = program->source;
+               const deUint64          compileStartTime        = deGetMicroseconds();
+               const spv_result_t      compileOk                       = spvTextToBinary(context, spvSource.c_str(), spvSource.size(), &binary, &diagnostic);
+
+               buildInfo->source                       = spvSource;
                buildInfo->infoLog                      = diagnostic? diagnostic->error : ""; // \todo [2015-07-13 pyry] Include debug log?
                buildInfo->compileTimeUs        = deGetMicroseconds() - compileStartTime;
                buildInfo->compileOk            = (compileOk == SPV_SUCCESS);
+
+               dst->resize(binary->wordCount);
+               std::copy(&binary->code[0], &binary->code[0] + binary->wordCount, dst->begin());
+
+               spvBinaryDestroy(binary);
+               spvDiagnosticDestroy(diagnostic);
+               spvContextDestroy(context);
+
+               return compileOk == SPV_SUCCESS;
        }
+       catch (...)
+       {
+               spvBinaryDestroy(binary);
+               spvDiagnosticDestroy(diagnostic);
+               spvContextDestroy(context);
 
-       if (compileOk != SPV_SUCCESS)
-               TCU_FAIL("Failed to compile shader");
+               throw;
+       }
+}
 
-       dst->resize((int)binary->wordCount * sizeof(deUint32));
-#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
-       deMemcpy(&(*dst)[0], &binary->code[0], dst->size());
-#else
-#      error "Big-endian not supported"
-#endif
-       spvBinaryDestroy(binary);
-       spvDiagnosticDestroy(diagnostic);
-       spvContextDestroy(context);
-       return;
+void disassembleSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostream* dst)
+{
+       const spv_context       context         = spvContextCreate();
+       spv_text                        text            = DE_NULL;
+       spv_diagnostic          diagnostic      = DE_NULL;
+
+       if (!context)
+               throw std::bad_alloc();
+
+       try
+       {
+               const spv_result_t      result  = spvBinaryToText(context, binary, binarySizeInWords, 0, &text, &diagnostic);
+
+               if (result != SPV_SUCCESS)
+                       TCU_THROW(InternalError, "Disassembling SPIR-V failed");
+
+               *dst << text->str;
+
+               spvTextDestroy(text);
+               spvDiagnosticDestroy(diagnostic);
+               spvContextDestroy(context);
+       }
+       catch (...)
+       {
+               spvTextDestroy(text);
+               spvDiagnosticDestroy(diagnostic);
+               spvContextDestroy(context);
+
+               throw;
+       }
+}
+
+bool validateSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostream* infoLog)
+{
+       const spv_context       context         = spvContextCreate();
+       spv_diagnostic          diagnostic      = DE_NULL;
+
+       try
+       {
+               spv_const_binary_t      cbinary         = { binary, binarySizeInWords };
+               const spv_result_t      valid           = spvValidate(context, &cbinary, &diagnostic);
+
+               if (diagnostic)
+                       *infoLog << diagnostic->error;
+
+               spvDiagnosticDestroy(diagnostic);
+               spvContextDestroy(context);
+
+               return valid == SPV_SUCCESS;
+       }
+       catch (...)
+       {
+               spvDiagnosticDestroy(diagnostic);
+               spvContextDestroy(context);
+
+               throw;
+       }
 }
 
 #else // defined(DEQP_HAVE_SPIRV_TOOLS)
 
-void assembleSpirV (const SpirVAsmSource*, std::vector<deUint8>*, SpirVProgramInfo*)
+bool assembleSpirV (const SpirVAsmSource*, std::vector<deUint32>*, SpirVProgramInfo*)
 {
        TCU_THROW(NotSupportedError, "SPIR-V assembly not supported (DEQP_HAVE_SPIRV_TOOLS not defined)");
 }
 
+void disassembleSpirV (size_t, const deUint32*, std::ostream*)
+{
+       TCU_THROW(NotSupportedError, "SPIR-V disassembling not supported (DEQP_HAVE_SPIRV_TOOLS not defined)");
+}
+
+bool validateSpirV (size_t, const deUint32*, std::ostream*)
+{
+       TCU_THROW(NotSupportedError, "SPIR-V validation not supported (DEQP_HAVE_SPIRV_TOOLS not defined)");
+}
+
 #endif
 
 } // vk