123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- // Copyright (c) 2015-2016 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.
- #ifndef TEST_TEST_FIXTURE_H_
- #define TEST_TEST_FIXTURE_H_
- #include <string>
- #include <vector>
- #include "test/unit_spirv.h"
- namespace spvtest {
- // RAII for spv_context.
- struct ScopedContext {
- ScopedContext(spv_target_env env = SPV_ENV_UNIVERSAL_1_0)
- : context(spvContextCreate(env)) {}
- ~ScopedContext() { spvContextDestroy(context); }
- spv_context context;
- };
- // Common setup for TextToBinary tests. SetText() should be called to populate
- // the actual test text.
- template <typename T>
- class TextToBinaryTestBase : public T {
- public:
- // Shorthand for SPIR-V compilation result.
- using SpirvVector = std::vector<uint32_t>;
- // Offset into a SpirvVector at which the first instruction starts.
- static const SpirvVector::size_type kFirstInstruction = 5;
- TextToBinaryTestBase() : diagnostic(nullptr), text(), binary(nullptr) {
- char textStr[] = "substitute the text member variable with your test";
- text = {textStr, strlen(textStr)};
- }
- virtual ~TextToBinaryTestBase() {
- DestroyBinary();
- if (diagnostic) spvDiagnosticDestroy(diagnostic);
- }
- // Returns subvector v[from:end).
- SpirvVector Subvector(const SpirvVector& v, SpirvVector::size_type from) {
- assert(from <= v.size());
- return SpirvVector(v.begin() + from, v.end());
- }
- // Compiles SPIR-V text in the given assembly syntax format, asserting
- // compilation success. Returns the compiled code.
- SpirvVector CompileSuccessfully(const std::string& txt,
- spv_target_env env = SPV_ENV_UNIVERSAL_1_0) {
- DestroyBinary();
- DestroyDiagnostic();
- spv_result_t status =
- spvTextToBinary(ScopedContext(env).context, txt.c_str(), txt.size(),
- &binary, &diagnostic);
- EXPECT_EQ(SPV_SUCCESS, status) << txt;
- SpirvVector code_copy;
- if (status == SPV_SUCCESS) {
- code_copy = SpirvVector(binary->code, binary->code + binary->wordCount);
- DestroyBinary();
- } else {
- spvDiagnosticPrint(diagnostic);
- }
- return code_copy;
- }
- // Compiles SPIR-V text with the given format, asserting compilation failure.
- // Returns the error message(s).
- std::string CompileFailure(const std::string& txt,
- spv_target_env env = SPV_ENV_UNIVERSAL_1_0) {
- DestroyBinary();
- DestroyDiagnostic();
- EXPECT_NE(SPV_SUCCESS,
- spvTextToBinary(ScopedContext(env).context, txt.c_str(),
- txt.size(), &binary, &diagnostic))
- << txt;
- DestroyBinary();
- return diagnostic->error;
- }
- // Encodes SPIR-V text into binary and then decodes the binary using
- // given options. Returns the decoded text.
- std::string EncodeAndDecodeSuccessfully(
- const std::string& txt,
- uint32_t disassemble_options = SPV_BINARY_TO_TEXT_OPTION_NONE,
- spv_target_env env = SPV_ENV_UNIVERSAL_1_0) {
- DestroyBinary();
- DestroyDiagnostic();
- ScopedContext context(env);
- disassemble_options |= SPV_BINARY_TO_TEXT_OPTION_NO_HEADER;
- spv_result_t error = spvTextToBinary(context.context, txt.c_str(),
- txt.size(), &binary, &diagnostic);
- if (error) {
- spvDiagnosticPrint(diagnostic);
- spvDiagnosticDestroy(diagnostic);
- }
- EXPECT_EQ(SPV_SUCCESS, error);
- if (!binary) return "";
- spv_text decoded_text;
- error = spvBinaryToText(context.context, binary->code, binary->wordCount,
- disassemble_options, &decoded_text, &diagnostic);
- if (error) {
- spvDiagnosticPrint(diagnostic);
- spvDiagnosticDestroy(diagnostic);
- }
- EXPECT_EQ(SPV_SUCCESS, error) << txt;
- const std::string decoded_string = decoded_text->str;
- spvTextDestroy(decoded_text);
- return decoded_string;
- }
- // Encodes SPIR-V text into binary. This is expected to succeed.
- // The given words are then appended to the binary, and the result
- // is then decoded. This is expected to fail.
- // Returns the error message.
- std::string EncodeSuccessfullyDecodeFailed(
- const std::string& txt, const SpirvVector& words_to_append) {
- DestroyBinary();
- DestroyDiagnostic();
- SpirvVector code =
- spvtest::Concatenate({CompileSuccessfully(txt), words_to_append});
- spv_text decoded_text;
- EXPECT_NE(SPV_SUCCESS,
- spvBinaryToText(ScopedContext().context, code.data(), code.size(),
- SPV_BINARY_TO_TEXT_OPTION_NONE, &decoded_text,
- &diagnostic));
- if (diagnostic) {
- std::string error_message = diagnostic->error;
- spvDiagnosticDestroy(diagnostic);
- diagnostic = nullptr;
- return error_message;
- }
- return "";
- }
- // Compiles SPIR-V text, asserts success, and returns the words representing
- // the instructions. In particular, skip the words in the SPIR-V header.
- SpirvVector CompiledInstructions(const std::string& txt,
- spv_target_env env = SPV_ENV_UNIVERSAL_1_0) {
- const SpirvVector code = CompileSuccessfully(txt, env);
- SpirvVector result;
- // Extract just the instructions.
- // If the code fails to compile, then return the empty vector.
- // In any case, don't crash or invoke undefined behaviour.
- if (code.size() >= kFirstInstruction)
- result = Subvector(code, kFirstInstruction);
- return result;
- }
- void SetText(const std::string& code) {
- textString = code;
- text.str = textString.c_str();
- text.length = textString.size();
- }
- // Destroys the binary, if it exists.
- void DestroyBinary() {
- spvBinaryDestroy(binary);
- binary = nullptr;
- }
- // Destroys the diagnostic, if it exists.
- void DestroyDiagnostic() {
- spvDiagnosticDestroy(diagnostic);
- diagnostic = nullptr;
- }
- spv_diagnostic diagnostic;
- std::string textString;
- spv_text_t text;
- spv_binary binary;
- };
- using TextToBinaryTest = TextToBinaryTestBase<::testing::Test>;
- } // namespace spvtest
- using RoundTripTest =
- spvtest::TextToBinaryTestBase<::testing::TestWithParam<std::string>>;
- #endif // TEST_TEST_FIXTURE_H_
|