1fd4e5da5Sopenharmony_ci// Copyright (c) 2018 Google LLC
2fd4e5da5Sopenharmony_ci//
3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
6fd4e5da5Sopenharmony_ci//
7fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8fd4e5da5Sopenharmony_ci//
9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
13fd4e5da5Sopenharmony_ci// limitations under the License.
14fd4e5da5Sopenharmony_ci
15fd4e5da5Sopenharmony_ci#include "test/reduce/reduce_test_util.h"
16fd4e5da5Sopenharmony_ci
17fd4e5da5Sopenharmony_ci#include <iostream>
18fd4e5da5Sopenharmony_ci
19fd4e5da5Sopenharmony_ci#include "tools/io.h"
20fd4e5da5Sopenharmony_ci
21fd4e5da5Sopenharmony_cinamespace spvtools {
22fd4e5da5Sopenharmony_cinamespace reduce {
23fd4e5da5Sopenharmony_ci
24fd4e5da5Sopenharmony_ciconst spvtools::MessageConsumer kConsoleMessageConsumer =
25fd4e5da5Sopenharmony_ci    [](spv_message_level_t level, const char*, const spv_position_t& position,
26fd4e5da5Sopenharmony_ci       const char* message) -> void {
27fd4e5da5Sopenharmony_ci  switch (level) {
28fd4e5da5Sopenharmony_ci    case SPV_MSG_FATAL:
29fd4e5da5Sopenharmony_ci    case SPV_MSG_INTERNAL_ERROR:
30fd4e5da5Sopenharmony_ci    case SPV_MSG_ERROR:
31fd4e5da5Sopenharmony_ci      std::cerr << "error: line " << position.index << ": " << message
32fd4e5da5Sopenharmony_ci                << std::endl;
33fd4e5da5Sopenharmony_ci      break;
34fd4e5da5Sopenharmony_ci    case SPV_MSG_WARNING:
35fd4e5da5Sopenharmony_ci      std::cout << "warning: line " << position.index << ": " << message
36fd4e5da5Sopenharmony_ci                << std::endl;
37fd4e5da5Sopenharmony_ci      break;
38fd4e5da5Sopenharmony_ci    case SPV_MSG_INFO:
39fd4e5da5Sopenharmony_ci      std::cout << "info: line " << position.index << ": " << message
40fd4e5da5Sopenharmony_ci                << std::endl;
41fd4e5da5Sopenharmony_ci      break;
42fd4e5da5Sopenharmony_ci    default:
43fd4e5da5Sopenharmony_ci      break;
44fd4e5da5Sopenharmony_ci  }
45fd4e5da5Sopenharmony_ci};
46fd4e5da5Sopenharmony_ci
47fd4e5da5Sopenharmony_civoid CheckEqual(const spv_target_env env,
48fd4e5da5Sopenharmony_ci                const std::vector<uint32_t>& expected_binary,
49fd4e5da5Sopenharmony_ci                const std::vector<uint32_t>& actual_binary) {
50fd4e5da5Sopenharmony_ci  if (expected_binary != actual_binary) {
51fd4e5da5Sopenharmony_ci    SpirvTools t(env);
52fd4e5da5Sopenharmony_ci    std::string expected_disassembled;
53fd4e5da5Sopenharmony_ci    std::string actual_disassembled;
54fd4e5da5Sopenharmony_ci    ASSERT_TRUE(t.Disassemble(expected_binary, &expected_disassembled,
55fd4e5da5Sopenharmony_ci                              kReduceDisassembleOption));
56fd4e5da5Sopenharmony_ci    ASSERT_TRUE(t.Disassemble(actual_binary, &actual_disassembled,
57fd4e5da5Sopenharmony_ci                              kReduceDisassembleOption));
58fd4e5da5Sopenharmony_ci    ASSERT_EQ(expected_disassembled, actual_disassembled);
59fd4e5da5Sopenharmony_ci  }
60fd4e5da5Sopenharmony_ci}
61fd4e5da5Sopenharmony_ci
62fd4e5da5Sopenharmony_civoid CheckEqual(const spv_target_env env, const std::string& expected_text,
63fd4e5da5Sopenharmony_ci                const std::vector<uint32_t>& actual_binary) {
64fd4e5da5Sopenharmony_ci  std::vector<uint32_t> expected_binary;
65fd4e5da5Sopenharmony_ci  SpirvTools t(env);
66fd4e5da5Sopenharmony_ci  ASSERT_TRUE(
67fd4e5da5Sopenharmony_ci      t.Assemble(expected_text, &expected_binary, kReduceAssembleOption));
68fd4e5da5Sopenharmony_ci  CheckEqual(env, expected_binary, actual_binary);
69fd4e5da5Sopenharmony_ci}
70fd4e5da5Sopenharmony_ci
71fd4e5da5Sopenharmony_civoid CheckEqual(const spv_target_env env, const std::string& expected_text,
72fd4e5da5Sopenharmony_ci                const opt::IRContext* actual_ir) {
73fd4e5da5Sopenharmony_ci  std::vector<uint32_t> actual_binary;
74fd4e5da5Sopenharmony_ci  actual_ir->module()->ToBinary(&actual_binary, false);
75fd4e5da5Sopenharmony_ci  CheckEqual(env, expected_text, actual_binary);
76fd4e5da5Sopenharmony_ci}
77fd4e5da5Sopenharmony_ci
78fd4e5da5Sopenharmony_civoid CheckValid(spv_target_env env, const opt::IRContext* ir) {
79fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
80fd4e5da5Sopenharmony_ci  ir->module()->ToBinary(&binary, false);
81fd4e5da5Sopenharmony_ci  SpirvTools tools(env);
82fd4e5da5Sopenharmony_ci  tools.SetMessageConsumer(kConsoleMessageConsumer);
83fd4e5da5Sopenharmony_ci  ASSERT_TRUE(tools.Validate(binary));
84fd4e5da5Sopenharmony_ci}
85fd4e5da5Sopenharmony_ci
86fd4e5da5Sopenharmony_cistd::string ToString(spv_target_env env, const opt::IRContext* ir) {
87fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
88fd4e5da5Sopenharmony_ci  ir->module()->ToBinary(&binary, false);
89fd4e5da5Sopenharmony_ci  SpirvTools t(env);
90fd4e5da5Sopenharmony_ci  std::string result;
91fd4e5da5Sopenharmony_ci  t.Disassemble(binary, &result, kReduceDisassembleOption);
92fd4e5da5Sopenharmony_ci  return result;
93fd4e5da5Sopenharmony_ci}
94fd4e5da5Sopenharmony_ci
95fd4e5da5Sopenharmony_civoid NopDiagnostic(spv_message_level_t /*level*/, const char* /*source*/,
96fd4e5da5Sopenharmony_ci                   const spv_position_t& /*position*/,
97fd4e5da5Sopenharmony_ci                   const char* /*message*/) {}
98fd4e5da5Sopenharmony_ci
99fd4e5da5Sopenharmony_civoid CLIMessageConsumer(spv_message_level_t level, const char*,
100fd4e5da5Sopenharmony_ci                        const spv_position_t& position, const char* message) {
101fd4e5da5Sopenharmony_ci  switch (level) {
102fd4e5da5Sopenharmony_ci    case SPV_MSG_FATAL:
103fd4e5da5Sopenharmony_ci    case SPV_MSG_INTERNAL_ERROR:
104fd4e5da5Sopenharmony_ci    case SPV_MSG_ERROR:
105fd4e5da5Sopenharmony_ci      std::cerr << "error: line " << position.index << ": " << message
106fd4e5da5Sopenharmony_ci                << std::endl;
107fd4e5da5Sopenharmony_ci      break;
108fd4e5da5Sopenharmony_ci    case SPV_MSG_WARNING:
109fd4e5da5Sopenharmony_ci      std::cout << "warning: line " << position.index << ": " << message
110fd4e5da5Sopenharmony_ci                << std::endl;
111fd4e5da5Sopenharmony_ci      break;
112fd4e5da5Sopenharmony_ci    case SPV_MSG_INFO:
113fd4e5da5Sopenharmony_ci      std::cout << "info: line " << position.index << ": " << message
114fd4e5da5Sopenharmony_ci                << std::endl;
115fd4e5da5Sopenharmony_ci      break;
116fd4e5da5Sopenharmony_ci    default:
117fd4e5da5Sopenharmony_ci      break;
118fd4e5da5Sopenharmony_ci  }
119fd4e5da5Sopenharmony_ci}
120fd4e5da5Sopenharmony_ci
121fd4e5da5Sopenharmony_civoid DumpShader(opt::IRContext* context, const char* filename) {
122fd4e5da5Sopenharmony_ci  std::vector<uint32_t> binary;
123fd4e5da5Sopenharmony_ci  context->module()->ToBinary(&binary, false);
124fd4e5da5Sopenharmony_ci  DumpShader(binary, filename);
125fd4e5da5Sopenharmony_ci}
126fd4e5da5Sopenharmony_ci
127fd4e5da5Sopenharmony_civoid DumpShader(const std::vector<uint32_t>& binary, const char* filename) {
128fd4e5da5Sopenharmony_ci  auto write_file_succeeded =
129fd4e5da5Sopenharmony_ci      WriteFile(filename, "wb", &binary[0], binary.size());
130fd4e5da5Sopenharmony_ci  if (!write_file_succeeded) {
131fd4e5da5Sopenharmony_ci    std::cerr << "Failed to dump shader" << std::endl;
132fd4e5da5Sopenharmony_ci  }
133fd4e5da5Sopenharmony_ci}
134fd4e5da5Sopenharmony_ci
135fd4e5da5Sopenharmony_ci}  // namespace reduce
136fd4e5da5Sopenharmony_ci}  // namespace spvtools
137