• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2023 Valve Corporation
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #ifndef NIR_TESTS_NIR_TEST_H
7 #define NIR_TESTS_NIR_TEST_H
8 
9 #include <gtest/gtest.h>
10 
11 #include "nir.h"
12 #include "nir_builder.h"
13 
14 #include "util/memstream.h"
15 
16 struct nir_reference_shader {
17    const char *string;
18    const char *file;
19    uint32_t line;
20 };
21 
22 class nir_test : public ::testing::Test {
23  protected:
nir_test(const char * name)24    nir_test(const char *name)
25       : nir_test(name, MESA_SHADER_COMPUTE)
26    {
27    }
28 
nir_test(const char * name,gl_shader_stage stage)29    nir_test(const char *name, gl_shader_stage stage)
30    {
31       glsl_type_singleton_init_or_ref();
32 
33       _b = nir_builder_init_simple_shader(stage, &options, "%s", name);
34       b = &_b;
35 
36       b->shader->info.next_stage = MESA_SHADER_NONE;
37       b->shader->info.internal = false;
38    }
39 
~nir_test()40    virtual ~nir_test()
41    {
42       if (HasFailure()) {
43          printf("\nShader from the failed test:\n\n");
44          nir_print_shader(b->shader, stdout);
45       }
46 
47       ralloc_free(b->shader);
48 
49       glsl_type_singleton_decref();
50    }
51 
52    /** Compares the NIR shader against the string of a reference shader. */
check_nir_string(struct nir_reference_shader reference)53    void check_nir_string(struct nir_reference_shader reference)
54    {
55       nir_index_ssa_defs(b->impl);
56 
57       char *result = NULL;
58       size_t result_size = 0;
59       struct u_memstream mem;
60       if (!u_memstream_open(&mem, &result, &result_size))
61          return;
62 
63       FILE * memf = u_memstream_get(&mem);
64       nir_print_shader(b->shader, memf);
65       u_memstream_close(&mem);
66 
67       const char *expected = reference.string;
68 
69       /* Use a custom comparison that ignores spaces since spaces are not
70        * relevant for correctness. This is also intended to be used when
71        * specifying the expected shader for indentation. Indentation can
72        * not simply be handled by nir_print_shader because that would require
73        * computing the indentation.
74        */
75       const char *result_iter = result;
76       size_t result_length = strlen(result);
77       const char *expected_iter = expected;
78       size_t expected_length = strlen(expected);
79 
80       bool failed = false;
81 
82       while (result_iter < result + result_length && expected_iter < expected + expected_length) {
83          if (isspace(*result_iter)) {
84             result_iter++;
85             continue;
86          }
87 
88          if (isspace(*expected_iter)) {
89             expected_iter++;
90             continue;
91          }
92 
93          if (*result_iter != *expected_iter) {
94             ADD_FAILURE();
95             failed = true;
96             break;
97          }
98 
99          result_iter++;
100          expected_iter++;
101       }
102 
103       if (!failed) {
104          for (; result_iter < result + result_length; result_iter++) {
105             if (!isspace(*result_iter)) {
106                ADD_FAILURE();
107                failed = true;
108                break;
109             }
110          }
111       }
112 
113       if (!failed) {
114          for (; expected_iter < expected + expected_length; expected_iter++) {
115             if (!isspace(*expected_iter)) {
116                ADD_FAILURE();
117                failed = true;
118                break;
119             }
120          }
121       }
122 
123       if (failed || debug_get_bool_option("NIR_TEST_DUMP_SHADERS", false))
124          printf("Got:\n%s\nExpected (%s:%u):\n%s\n", result, reference.file, reference.line, expected);
125 
126       free(result);
127    }
128 
129    nir_shader_compiler_options options = {};
130    nir_builder _b;
131    nir_builder *b;
132 };
133 
134 #define NIR_REFERENCE_SHADER(expected) nir_reference_shader{.string = expected, .file = __FILE__, .line = __LINE__}
135 
136 #endif
137