Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/shaderc
Path: blob/main/libshaderc/src/shaderc_cpp_test.cc
1558 views
1
// Copyright 2015 The Shaderc Authors. All rights reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <gmock/gmock.h>
16
#include <gtest/gtest.h>
17
18
#include <memory>
19
#include <thread>
20
#include <unordered_map>
21
22
#include "common_shaders_for_test.h"
23
#include "shaderc/shaderc.hpp"
24
#include "spirv-tools/libspirv.hpp"
25
#include "spirv/unified1/spirv.hpp"
26
27
namespace {
28
29
using shaderc::AssemblyCompilationResult;
30
using shaderc::CompileOptions;
31
using shaderc::PreprocessedSourceCompilationResult;
32
using shaderc::SpvCompilationResult;
33
using testing::Each;
34
using testing::Eq;
35
using testing::HasSubstr;
36
using testing::Not;
37
38
// Helper function to check if the compilation result indicates a successful
39
// compilation.
40
template <typename T>
41
bool CompilationResultIsSuccess(const shaderc::CompilationResult<T>& result) {
42
return result.GetCompilationStatus() == shaderc_compilation_status_success;
43
}
44
45
// Examines whether a compilation result has valid SPIR-V code, by checking the
46
// magic number in the fixed postion of the byte array in the result object.
47
// Returns true if the magic number is found at the correct postion, otherwise
48
// returns false.
49
bool IsValidSpv(const SpvCompilationResult& result) {
50
if (!CompilationResultIsSuccess(result)) return false;
51
size_t length_in_words = result.cend() - result.cbegin();
52
if (length_in_words < 5) return false;
53
const uint32_t* bytes = result.cbegin();
54
return bytes[0] == spv::MagicNumber;
55
}
56
57
// Compiles a shader and returns true if the result is valid SPIR-V. The
58
// input_file_name is set to "shader".
59
bool CompilesToValidSpv(const shaderc::Compiler& compiler,
60
const std::string& shader, shaderc_shader_kind kind) {
61
return IsValidSpv(compiler.CompileGlslToSpv(shader, kind, "shader"));
62
}
63
64
// Compiles a shader with options and returns true if the result is valid
65
// SPIR-V. The input_file_name is set to "shader".
66
bool CompilesToValidSpv(const shaderc::Compiler& compiler,
67
const std::string& shader, shaderc_shader_kind kind,
68
const CompileOptions& options) {
69
return IsValidSpv(compiler.CompileGlslToSpv(shader, kind, "shader", options));
70
}
71
72
// Returns the compiler's output from a compilation result as a string.
73
template <typename T>
74
std::string CompilerOutputAsString(
75
const shaderc::CompilationResult<T>& result) {
76
return std::string(reinterpret_cast<const char*>(result.cbegin()),
77
reinterpret_cast<const char*>(result.cend()));
78
}
79
80
class CppInterface : public testing::Test {
81
protected:
82
// Compiles a shader and returns true on success, false on failure.
83
// The input file name is set to "shader" by default.
84
bool CompilationSuccess(const std::string& shader,
85
shaderc_shader_kind kind) const {
86
return compiler_
87
.CompileGlslToSpv(shader.c_str(), shader.length(), kind,
88
"shader")
89
.GetCompilationStatus() == shaderc_compilation_status_success;
90
}
91
92
// Compiles a shader with options and returns true on success, false on
93
// failure.
94
// The input file name is set to "shader" by default.
95
bool CompilationSuccess(const std::string& shader, shaderc_shader_kind kind,
96
const CompileOptions& options) const {
97
return compiler_
98
.CompileGlslToSpv(shader.c_str(), shader.length(), kind,
99
"shader", options)
100
.GetCompilationStatus() == shaderc_compilation_status_success;
101
}
102
103
// Compiles a shader, asserts compilation success, and returns the warning
104
// messages.
105
// The input file name is set to "shader" by default.
106
std::string CompilationWarnings(
107
const std::string& shader, shaderc_shader_kind kind,
108
// This could default to options_, but that can
109
// be easily confused with a no-options-provided
110
// case:
111
const CompileOptions& options) {
112
const auto compilation_result =
113
compiler_.CompileGlslToSpv(shader, kind, "shader", options);
114
EXPECT_TRUE(CompilationResultIsSuccess(compilation_result)) << kind << '\n'
115
<< shader;
116
return compilation_result.GetErrorMessage();
117
}
118
119
// Compiles a shader, asserts compilation fail, and returns the error
120
// messages.
121
std::string CompilationErrors(const std::string& shader,
122
shaderc_shader_kind kind,
123
// This could default to options_, but that can
124
// be easily confused with a no-options-provided
125
// case:
126
const CompileOptions& options) {
127
const auto compilation_result =
128
compiler_.CompileGlslToSpv(shader, kind, "shader", options);
129
EXPECT_FALSE(CompilationResultIsSuccess(compilation_result)) << kind << '\n'
130
<< shader;
131
return compilation_result.GetErrorMessage();
132
}
133
134
// Assembles the given SPIR-V assembly and returns true on success.
135
bool AssemblingSuccess(const std::string& shader,
136
const CompileOptions& options) const {
137
return compiler_.AssembleToSpv(shader, options).GetCompilationStatus() ==
138
shaderc_compilation_status_success;
139
}
140
141
// Assembles the given SPIR-V assembly and returns true if the result contains
142
// a valid SPIR-V module.
143
bool AssemblingValid(const std::string& shader,
144
const CompileOptions& options) const {
145
return IsValidSpv(compiler_.AssembleToSpv(shader, options));
146
}
147
148
// Compiles a shader, expects compilation success, and returns the output
149
// bytes.
150
// The input file name is set to "shader" by default.
151
std::string CompilationOutput(const std::string& shader,
152
shaderc_shader_kind kind,
153
const CompileOptions& options) const {
154
const auto compilation_result =
155
compiler_.CompileGlslToSpv(shader, kind, "shader", options);
156
EXPECT_TRUE(CompilationResultIsSuccess(compilation_result)) << kind << '\n';
157
// Need to make sure you get complete binary data, including embedded nulls.
158
return CompilerOutputAsString(compilation_result);
159
}
160
161
// Compiles a shader to SPIR-V assembly, expects compilation success, and
162
// returns the output bytes.
163
// The input file name is set to "shader" by default.
164
std::string AssemblyOutput(const std::string& shader,
165
shaderc_shader_kind kind,
166
const CompileOptions& options) const {
167
const auto compilation_result =
168
compiler_.CompileGlslToSpvAssembly(shader, kind, "shader", options);
169
EXPECT_TRUE(CompilationResultIsSuccess(compilation_result)) << kind << '\n';
170
// Need to make sure you get complete binary data, including embedded nulls.
171
return CompilerOutputAsString(compilation_result);
172
}
173
174
// For compiling shaders in subclass tests:
175
shaderc::Compiler compiler_;
176
CompileOptions options_;
177
};
178
179
TEST_F(CppInterface, CompilerValidUponConstruction) {
180
EXPECT_TRUE(compiler_.IsValid());
181
}
182
183
TEST_F(CppInterface, MultipleCalls) {
184
shaderc::Compiler compiler1, compiler2, compiler3;
185
EXPECT_TRUE(compiler1.IsValid());
186
EXPECT_TRUE(compiler2.IsValid());
187
EXPECT_TRUE(compiler3.IsValid());
188
}
189
190
#ifndef SHADERC_DISABLE_THREADED_TESTS
191
TEST_F(CppInterface, MultipleThreadsInitializing) {
192
std::unique_ptr<shaderc::Compiler> compiler1;
193
std::unique_ptr<shaderc::Compiler> compiler2;
194
std::unique_ptr<shaderc::Compiler> compiler3;
195
std::thread t1([&compiler1]() {
196
compiler1 = std::unique_ptr<shaderc::Compiler>(new shaderc::Compiler());
197
});
198
std::thread t2([&compiler2]() {
199
compiler2 = std::unique_ptr<shaderc::Compiler>(new shaderc::Compiler());
200
});
201
std::thread t3([&compiler3]() {
202
compiler3 = std::unique_ptr<shaderc::Compiler>(new shaderc::Compiler());
203
});
204
t1.join();
205
t2.join();
206
t3.join();
207
EXPECT_TRUE(compiler1->IsValid());
208
EXPECT_TRUE(compiler2->IsValid());
209
EXPECT_TRUE(compiler3->IsValid());
210
}
211
#endif
212
213
TEST_F(CppInterface, CompilerMoves) {
214
shaderc::Compiler compiler2(std::move(compiler_));
215
ASSERT_FALSE(compiler_.IsValid());
216
ASSERT_TRUE(compiler2.IsValid());
217
}
218
219
TEST_F(CppInterface, EmptyString) {
220
EXPECT_FALSE(CompilationSuccess("", shaderc_glsl_vertex_shader));
221
EXPECT_FALSE(CompilationSuccess("", shaderc_glsl_fragment_shader));
222
}
223
224
TEST_F(CppInterface, AssembleEmptyString) {
225
EXPECT_TRUE(AssemblingSuccess("", options_));
226
}
227
228
TEST_F(CppInterface, ResultObjectMoves) {
229
SpvCompilationResult result = compiler_.CompileGlslToSpv(
230
kMinimalShader, shaderc_glsl_vertex_shader, "shader");
231
EXPECT_TRUE(CompilationResultIsSuccess(result));
232
const SpvCompilationResult result2(std::move(result));
233
EXPECT_FALSE(CompilationResultIsSuccess(result));
234
EXPECT_TRUE(CompilationResultIsSuccess(result2));
235
}
236
237
TEST_F(CppInterface, GarbageString) {
238
EXPECT_FALSE(CompilationSuccess("jfalkds", shaderc_glsl_vertex_shader));
239
EXPECT_FALSE(CompilationSuccess("jfalkds", shaderc_glsl_fragment_shader));
240
}
241
242
TEST_F(CppInterface, AssembleGarbageString) {
243
const auto result = compiler_.AssembleToSpv("jfalkds", options_);
244
EXPECT_FALSE(CompilationResultIsSuccess(result));
245
EXPECT_EQ(0u, result.GetNumWarnings());
246
EXPECT_EQ(1u, result.GetNumErrors());
247
}
248
249
// TODO(antiagainst): right now there is no assembling difference for all the
250
// target environments exposed by shaderc. So the following is just testing the
251
// target environment is accepted.
252
TEST_F(CppInterface, AssembleTargetEnv) {
253
options_.SetTargetEnvironment(shaderc_target_env_opengl, 0);
254
EXPECT_TRUE(AssemblingValid("OpCapability Shader", options_));
255
}
256
257
TEST_F(CppInterface, MinimalShader) {
258
EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalShader,
259
shaderc_glsl_vertex_shader));
260
EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalShader,
261
shaderc_glsl_fragment_shader));
262
}
263
264
TEST_F(CppInterface, AssembleMinimalShader) {
265
EXPECT_TRUE(AssemblingValid(kMinimalShaderAssembly, options_));
266
}
267
268
TEST_F(CppInterface, BasicOptions) {
269
EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalShader,
270
shaderc_glsl_vertex_shader, options_));
271
EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalShader,
272
shaderc_glsl_fragment_shader, options_));
273
}
274
275
TEST_F(CppInterface, CopiedOptions) {
276
EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalShader,
277
shaderc_glsl_vertex_shader, options_));
278
CompileOptions copied_options(options_);
279
EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalShader,
280
shaderc_glsl_fragment_shader, copied_options));
281
}
282
283
TEST_F(CppInterface, MovedOptions) {
284
EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalShader,
285
shaderc_glsl_vertex_shader, options_));
286
CompileOptions copied_options(std::move(options_));
287
EXPECT_TRUE(CompilesToValidSpv(compiler_, kMinimalShader,
288
shaderc_glsl_fragment_shader, copied_options));
289
}
290
291
TEST_F(CppInterface, StdAndCString) {
292
const SpvCompilationResult result1 =
293
compiler_.CompileGlslToSpv(kMinimalShader, strlen(kMinimalShader),
294
shaderc_glsl_fragment_shader, "shader");
295
const SpvCompilationResult result2 = compiler_.CompileGlslToSpv(
296
std::string(kMinimalShader), shaderc_glsl_fragment_shader, "shader");
297
EXPECT_TRUE(CompilationResultIsSuccess(result1));
298
EXPECT_TRUE(CompilationResultIsSuccess(result2));
299
EXPECT_EQ(std::vector<uint32_t>(result1.cbegin(), result1.cend()),
300
std::vector<uint32_t>(result2.cbegin(), result2.cend()));
301
}
302
303
TEST_F(CppInterface, ErrorsReported) {
304
const SpvCompilationResult result = compiler_.CompileGlslToSpv(
305
"int f(){return wrongname;}", shaderc_glsl_vertex_shader, "shader");
306
ASSERT_FALSE(CompilationResultIsSuccess(result));
307
EXPECT_THAT(result.GetErrorMessage(), HasSubstr("wrongname"));
308
}
309
310
#ifndef SHADERC_DISABLE_THREADED_TESTS
311
TEST_F(CppInterface, MultipleThreadsCalling) {
312
bool results[10];
313
std::vector<std::thread> threads;
314
for (auto& r : results) {
315
threads.emplace_back([this, &r]() {
316
r = CompilationSuccess(kMinimalShader, shaderc_glsl_vertex_shader);
317
});
318
}
319
for (auto& t : threads) {
320
t.join();
321
}
322
EXPECT_THAT(results, Each(true));
323
}
324
#endif
325
326
TEST_F(CppInterface, AccessorsOnNullResultObject) {
327
const SpvCompilationResult result(nullptr);
328
EXPECT_FALSE(CompilationResultIsSuccess(result));
329
EXPECT_EQ(std::string(), result.GetErrorMessage());
330
EXPECT_EQ(result.cend(), result.cbegin());
331
EXPECT_EQ(nullptr, result.cbegin());
332
EXPECT_EQ(nullptr, result.cend());
333
EXPECT_EQ(nullptr, result.begin());
334
EXPECT_EQ(nullptr, result.end());
335
}
336
337
TEST_F(CppInterface, MacroCompileOptions) {
338
options_.AddMacroDefinition("E", "main");
339
const std::string kMinimalExpandedShader = "#version 150\nvoid E(){}";
340
const std::string kMinimalDoubleExpandedShader = "#version 150\nF E(){}";
341
EXPECT_TRUE(CompilationSuccess(kMinimalExpandedShader,
342
shaderc_glsl_vertex_shader, options_));
343
344
CompileOptions cloned_options(options_);
345
// The simplest should still compile with the cloned options.
346
EXPECT_TRUE(CompilationSuccess(kMinimalExpandedShader,
347
shaderc_glsl_vertex_shader, cloned_options));
348
349
EXPECT_FALSE(CompilationSuccess(kMinimalDoubleExpandedShader,
350
shaderc_glsl_vertex_shader, cloned_options));
351
352
cloned_options.AddMacroDefinition("F", "void");
353
// This should still not work with the original options.
354
EXPECT_FALSE(CompilationSuccess(kMinimalDoubleExpandedShader,
355
shaderc_glsl_vertex_shader, options_));
356
// This should work with the cloned options that have the additional
357
// parameter.
358
EXPECT_TRUE(CompilationSuccess(kMinimalDoubleExpandedShader,
359
shaderc_glsl_vertex_shader, cloned_options));
360
}
361
362
TEST_F(CppInterface, D_DisassemblyOption) {
363
const AssemblyCompilationResult result = compiler_.CompileGlslToSpvAssembly(
364
kMinimalShader, shaderc_glsl_vertex_shader, "shader", options_);
365
EXPECT_TRUE(CompilationResultIsSuccess(result));
366
// This should work with both the glslang disassembly format and the
367
// SPIR-V Tools assembly format.
368
EXPECT_THAT(CompilerOutputAsString(result), HasSubstr("Capability Shader"));
369
EXPECT_THAT(CompilerOutputAsString(result), HasSubstr("MemoryModel"));
370
371
CompileOptions cloned_options(options_);
372
auto result_from_cloned_options = compiler_.CompileGlslToSpvAssembly(
373
kMinimalShader, shaderc_glsl_vertex_shader, "shader", cloned_options);
374
EXPECT_TRUE(CompilationResultIsSuccess(result_from_cloned_options));
375
// The mode should be carried into any clone of the original option object.
376
EXPECT_THAT(CompilerOutputAsString(result_from_cloned_options),
377
HasSubstr("Capability Shader"));
378
EXPECT_THAT(CompilerOutputAsString(result_from_cloned_options),
379
HasSubstr("MemoryModel"));
380
}
381
382
TEST_F(CppInterface, DisassembleMinimalShader) {
383
const AssemblyCompilationResult result = compiler_.CompileGlslToSpvAssembly(
384
kMinimalShader, shaderc_glsl_vertex_shader, "shader", options_);
385
EXPECT_TRUE(CompilationResultIsSuccess(result));
386
for (const auto& substring : kMinimalShaderDisassemblySubstrings) {
387
EXPECT_THAT(CompilerOutputAsString(result), HasSubstr(substring));
388
}
389
}
390
391
TEST_F(CppInterface, ForcedVersionProfileCorrectStd) {
392
// Forces the version and profile to 450core, which fixes the missing
393
// #version.
394
options_.SetForcedVersionProfile(450, shaderc_profile_core);
395
EXPECT_TRUE(CompilesToValidSpv(compiler_, kCoreVertShaderWithoutVersion,
396
shaderc_glsl_vertex_shader, options_));
397
}
398
399
TEST_F(CppInterface, ForcedVersionProfileCorrectStdClonedOptions) {
400
// Forces the version and profile to 450core, which fixes the missing
401
// #version.
402
options_.SetForcedVersionProfile(450, shaderc_profile_core);
403
CompileOptions cloned_options(options_);
404
EXPECT_TRUE(CompilesToValidSpv(compiler_, kCoreVertShaderWithoutVersion,
405
shaderc_glsl_vertex_shader, cloned_options));
406
}
407
408
TEST_F(CppInterface, ForcedVersionProfileInvalidModule) {
409
// Forces the version and profile to 310es, while the source module is invalid
410
// for this version of GLSL. Compilation should fail.
411
options_.SetForcedVersionProfile(310, shaderc_profile_es);
412
EXPECT_THAT(CompilationErrors(kCoreVertShaderWithoutVersion,
413
shaderc_glsl_vertex_shader, options_),
414
HasSubstr("error: 'gl_ClipDistance' : undeclared identifier\n"));
415
}
416
417
TEST_F(CppInterface, ForcedVersionProfileConflictingStd) {
418
// Forces the version and profile to 450core, which is in conflict with the
419
// #version in shader.
420
const std::string kVertexShader =
421
std::string("#version 310 es\n") + kCoreVertShaderWithoutVersion;
422
options_.SetForcedVersionProfile(450, shaderc_profile_core);
423
EXPECT_THAT(
424
CompilationWarnings(kVertexShader, shaderc_glsl_vertex_shader, options_),
425
HasSubstr("warning: (version, profile) forced to be (450, core), "
426
"while in source code it is (310, es)\n"));
427
}
428
429
TEST_F(CppInterface, ForcedVersionProfileUnknownVersionStd) {
430
// Forces the version and profile to 4242core, which is an unknown version.
431
options_.SetForcedVersionProfile(4242 /*unknown version*/,
432
shaderc_profile_core);
433
auto const errs =
434
CompilationErrors(kMinimalShader, shaderc_glsl_vertex_shader, options_);
435
EXPECT_THAT(errs,
436
HasSubstr("warning: (version, profile) forced to be (4242, core),"
437
" while in source code it is (140, none)\n"));
438
EXPECT_THAT(errs, HasSubstr("error: version not supported\n"));
439
}
440
441
TEST_F(CppInterface, ForcedVersionProfileVersionsBefore150) {
442
// Versions before 150 do not allow a profile token, shaderc_profile_none
443
// should be passed down as the profile parameter.
444
options_.SetForcedVersionProfile(140, shaderc_profile_none);
445
EXPECT_TRUE(
446
CompilationSuccess(kMinimalShader, shaderc_glsl_vertex_shader, options_));
447
}
448
449
TEST_F(CppInterface, ForcedVersionProfileRedundantProfileStd) {
450
// Forces the version and profile to 100core. But versions before 150 do not
451
// allow a profile token, compilation should fail.
452
options_.SetForcedVersionProfile(100, shaderc_profile_core);
453
EXPECT_THAT(
454
CompilationErrors(kMinimalShader, shaderc_glsl_vertex_shader, options_),
455
HasSubstr("error: #version: versions before 150 do not allow a profile "
456
"token\n"));
457
}
458
459
TEST_F(CppInterface, GenerateDebugInfoBinary) {
460
options_.SetGenerateDebugInfo();
461
const std::string binary_output =
462
CompilationOutput(kMinimalDebugInfoShader,
463
shaderc_glsl_vertex_shader, options_);
464
// The binary output should contain the name of the vector (debug_info_sample)
465
// null-terminated, as well as the whole original source.
466
std::string vector_name("debug_info_sample");
467
vector_name.resize(vector_name.size() + 1);
468
EXPECT_THAT(binary_output, HasSubstr(vector_name));
469
EXPECT_THAT(binary_output, HasSubstr(kMinimalDebugInfoShader));
470
}
471
472
TEST_F(CppInterface, GenerateDebugInfoBinaryClonedOptions) {
473
options_.SetGenerateDebugInfo();
474
CompileOptions cloned_options(options_);
475
const std::string binary_output =
476
CompilationOutput(kMinimalDebugInfoShader,
477
shaderc_glsl_vertex_shader, cloned_options);
478
// The binary output should contain the name of the vector (debug_info_sample)
479
// null-terminated, as well as the whole original source.
480
std::string vector_name("debug_info_sample");
481
vector_name.resize(vector_name.size() + 1);
482
EXPECT_THAT(binary_output, HasSubstr(vector_name));
483
EXPECT_THAT(binary_output, HasSubstr(kMinimalDebugInfoShader));
484
}
485
486
TEST_F(CppInterface, GenerateDebugInfoDisassembly) {
487
options_.SetGenerateDebugInfo();
488
// Debug info should also be emitted in disassembly mode.
489
// The output disassembly should contain the name of the vector:
490
// debug_info_sample.
491
EXPECT_THAT(AssemblyOutput(kMinimalDebugInfoShader,
492
shaderc_glsl_vertex_shader, options_),
493
HasSubstr("debug_info_sample"));
494
}
495
496
TEST_F(CppInterface, GenerateDebugInfoDisassemblyClonedOptions) {
497
options_.SetGenerateDebugInfo();
498
// Generate debug info mode should be carried to the cloned options.
499
CompileOptions cloned_options(options_);
500
EXPECT_THAT(CompilationOutput(kMinimalDebugInfoShader,
501
shaderc_glsl_vertex_shader, cloned_options),
502
HasSubstr("debug_info_sample"));
503
}
504
505
TEST_F(CppInterface, CompileAndOptimizeWithLevelZero) {
506
options_.SetOptimizationLevel(shaderc_optimization_level_zero);
507
const std::string disassembly_text =
508
AssemblyOutput(kMinimalShader, shaderc_glsl_vertex_shader, options_);
509
for (const auto& substring : kMinimalShaderDisassemblySubstrings) {
510
EXPECT_THAT(disassembly_text, HasSubstr(substring));
511
}
512
// Check that we still have debug instructions.
513
EXPECT_THAT(disassembly_text, HasSubstr("OpName"));
514
EXPECT_THAT(disassembly_text, HasSubstr("OpSource"));
515
}
516
517
TEST_F(CppInterface, CompileAndOptimizeWithLevelPerformance) {
518
options_.SetOptimizationLevel(shaderc_optimization_level_performance);
519
const std::string disassembly_text = AssemblyOutput(
520
kGlslMultipleFnShader, shaderc_glsl_fragment_shader, options_);
521
// Check that we do not have function calls anymore.
522
EXPECT_THAT(disassembly_text, Not(HasSubstr("OpFunctionCall")));
523
}
524
525
TEST_F(CppInterface, CompileAndOptimizeWithLevelSize) {
526
options_.SetOptimizationLevel(shaderc_optimization_level_size);
527
const std::string disassembly_text =
528
AssemblyOutput(kMinimalShader, shaderc_glsl_vertex_shader, options_);
529
for (const auto& substring : kMinimalShaderDisassemblySubstrings) {
530
EXPECT_THAT(disassembly_text, HasSubstr(substring));
531
}
532
// Check that we do not have debug instructions.
533
EXPECT_THAT(disassembly_text, Not(HasSubstr("OpName")));
534
EXPECT_THAT(disassembly_text, Not(HasSubstr("OpSource")));
535
}
536
537
TEST_F(CppInterface, CompileAndOptimizeForVulkan10Failure) {
538
options_.SetSourceLanguage(shaderc_source_language_hlsl);
539
options_.SetTargetEnvironment(shaderc_target_env_vulkan,
540
shaderc_env_version_vulkan_1_0);
541
options_.SetOptimizationLevel(shaderc_optimization_level_performance);
542
543
EXPECT_THAT(CompilationErrors(kHlslWaveActiveSumeComputeShader,
544
shaderc_compute_shader, options_),
545
// TODO(antiagainst): the error message can be improved to be more
546
// explicit regarding Vulkan 1.1
547
HasSubstr("compilation succeeded but failed to optimize: "
548
"Capability GroupNonUniform is not allowed by Vulkan "
549
"1.0 specification (or requires extension)"));
550
}
551
552
TEST_F(CppInterface, CompileAndOptimizeForVulkan11Success) {
553
options_.SetSourceLanguage(shaderc_source_language_hlsl);
554
options_.SetTargetEnvironment(shaderc_target_env_vulkan,
555
shaderc_env_version_vulkan_1_1);
556
options_.SetOptimizationLevel(shaderc_optimization_level_performance);
557
558
const std::string disassembly_text = AssemblyOutput(
559
kHlslWaveActiveSumeComputeShader, shaderc_compute_shader, options_);
560
EXPECT_THAT(disassembly_text, HasSubstr("OpGroupNonUniformIAdd"));
561
}
562
563
TEST_F(CppInterface, FollowingOptLevelOverridesPreviousOne) {
564
options_.SetOptimizationLevel(shaderc_optimization_level_size);
565
// Optimization level settings overridden by
566
options_.SetOptimizationLevel(shaderc_optimization_level_zero);
567
const std::string disassembly_text =
568
AssemblyOutput(kMinimalShader, shaderc_glsl_vertex_shader, options_);
569
for (const auto& substring : kMinimalShaderDisassemblySubstrings) {
570
EXPECT_THAT(disassembly_text, HasSubstr(substring));
571
}
572
// Check that we still have debug instructions.
573
EXPECT_THAT(disassembly_text, HasSubstr("OpName"));
574
EXPECT_THAT(disassembly_text, HasSubstr("OpSource"));
575
}
576
577
TEST_F(CppInterface, GenerateDebugInfoOverridesOptimizationLevel) {
578
options_.SetOptimizationLevel(shaderc_optimization_level_size);
579
// Optimization level settings overridden by
580
options_.SetGenerateDebugInfo();
581
const std::string disassembly_text =
582
AssemblyOutput(kMinimalShader, shaderc_glsl_vertex_shader, options_);
583
for (const auto& substring : kMinimalShaderDebugInfoDisassemblySubstrings) {
584
EXPECT_THAT(disassembly_text, HasSubstr(substring));
585
}
586
// Check that we still have debug instructions.
587
EXPECT_THAT(disassembly_text, HasSubstr("OpName"));
588
EXPECT_THAT(disassembly_text, HasSubstr("OpSource"));
589
}
590
591
TEST_F(CppInterface, GenerateDebugInfoProhibitsOptimizationLevel) {
592
// Setting generate debug info first also works.
593
options_.SetGenerateDebugInfo();
594
options_.SetOptimizationLevel(shaderc_optimization_level_size);
595
const std::string disassembly_text =
596
AssemblyOutput(kMinimalShader, shaderc_glsl_vertex_shader, options_);
597
for (const auto& substring : kMinimalShaderDebugInfoDisassemblySubstrings) {
598
EXPECT_THAT(disassembly_text, HasSubstr(substring));
599
}
600
// Check that we still have debug instructions.
601
EXPECT_THAT(disassembly_text, HasSubstr("OpName"));
602
EXPECT_THAT(disassembly_text, HasSubstr("OpSource"));
603
}
604
605
TEST_F(CppInterface, GetNumErrors) {
606
std::string shader(kTwoErrorsShader);
607
const SpvCompilationResult compilation_result =
608
compiler_.CompileGlslToSpv(kTwoErrorsShader, strlen(kTwoErrorsShader),
609
shaderc_glsl_vertex_shader, "shader");
610
EXPECT_FALSE(CompilationResultIsSuccess(compilation_result));
611
EXPECT_EQ(2u, compilation_result.GetNumErrors());
612
EXPECT_EQ(0u, compilation_result.GetNumWarnings());
613
}
614
615
TEST_F(CppInterface, GetNumWarnings) {
616
const SpvCompilationResult compilation_result =
617
compiler_.CompileGlslToSpv(kTwoWarningsShader, strlen(kTwoWarningsShader),
618
shaderc_glsl_vertex_shader, "shader");
619
EXPECT_TRUE(CompilationResultIsSuccess(compilation_result));
620
EXPECT_EQ(2u, compilation_result.GetNumWarnings());
621
EXPECT_EQ(0u, compilation_result.GetNumErrors());
622
}
623
624
TEST_F(CppInterface, ZeroErrorsZeroWarnings) {
625
const SpvCompilationResult compilation_result =
626
compiler_.CompileGlslToSpv(kMinimalShader, strlen(kMinimalShader),
627
shaderc_glsl_vertex_shader, "shader");
628
EXPECT_TRUE(CompilationResultIsSuccess(compilation_result));
629
EXPECT_EQ(0u, compilation_result.GetNumErrors());
630
EXPECT_EQ(0u, compilation_result.GetNumWarnings());
631
}
632
633
TEST_F(CppInterface, ErrorTypeUnknownShaderStage) {
634
// The shader kind/stage can not be determined, the error type field should
635
// indicate the error type is shaderc_shader_kind_error.
636
const SpvCompilationResult compilation_result =
637
compiler_.CompileGlslToSpv(kMinimalShader, strlen(kMinimalShader),
638
shaderc_glsl_infer_from_source, "shader");
639
EXPECT_EQ(shaderc_compilation_status_invalid_stage,
640
compilation_result.GetCompilationStatus());
641
}
642
643
TEST_F(CppInterface, ErrorTypeCompilationError) {
644
// The shader kind is valid, the result object's error type field should
645
// indicate this compilaion fails due to compilation errors.
646
const SpvCompilationResult compilation_result = compiler_.CompileGlslToSpv(
647
kTwoErrorsShader, shaderc_glsl_vertex_shader, "shader");
648
EXPECT_EQ(shaderc_compilation_status_compilation_error,
649
compilation_result.GetCompilationStatus());
650
}
651
652
TEST_F(CppInterface, ErrorTagIsInputFileName) {
653
std::string shader(kTwoErrorsShader);
654
const SpvCompilationResult compilation_result =
655
compiler_.CompileGlslToSpv(kTwoErrorsShader, strlen(kTwoErrorsShader),
656
shaderc_glsl_vertex_shader, "SampleInputFile");
657
// Expects compilation failure errors. The error tag should be
658
// 'SampleInputFile'
659
EXPECT_FALSE(CompilationResultIsSuccess(compilation_result));
660
EXPECT_THAT(compilation_result.GetErrorMessage(),
661
HasSubstr("SampleInputFile:3: error:"));
662
}
663
664
TEST_F(CppInterface, PreprocessingOnlyOption) {
665
const PreprocessedSourceCompilationResult result = compiler_.PreprocessGlsl(
666
kMinimalShaderWithMacro, shaderc_glsl_vertex_shader, "shader", options_);
667
EXPECT_TRUE(CompilationResultIsSuccess(result));
668
EXPECT_THAT(CompilerOutputAsString(result), HasSubstr("void main() { }"));
669
670
const std::string kMinimalShaderCloneOption =
671
"#version 140\n"
672
"#define E_CLONE_OPTION main\n"
673
"void E_CLONE_OPTION(){}\n";
674
CompileOptions cloned_options(options_);
675
const PreprocessedSourceCompilationResult result_from_cloned_options =
676
compiler_.PreprocessGlsl(kMinimalShaderCloneOption,
677
shaderc_glsl_vertex_shader, "shader",
678
cloned_options);
679
EXPECT_TRUE(CompilationResultIsSuccess(result_from_cloned_options));
680
EXPECT_THAT(CompilerOutputAsString(result_from_cloned_options),
681
HasSubstr("void main() { }"));
682
}
683
684
// A shader kind test case needs: 1) A shader text with or without #pragma
685
// annotation, 2) shader_kind.
686
struct ShaderKindTestCase {
687
const char* shader_;
688
shaderc_shader_kind shader_kind_;
689
};
690
691
// Test the shader kind deduction process. If the shader kind is one
692
// of the non-default ones, the compiler will just try to compile the
693
// source code in that specified shader kind. If the shader kind is
694
// shaderc_glsl_deduce_from_pragma, the compiler will determine the shader
695
// kind from #pragma annotation in the source code and emit error if none
696
// such annotation is found. When the shader kind is one of the default
697
// ones, the compiler will fall back to use the specified shader kind if
698
// and only if #pragma annoation is not found.
699
700
// Valid shader kind settings should generate valid SPIR-V code.
701
using ValidShaderKind = testing::TestWithParam<ShaderKindTestCase>;
702
703
TEST_P(ValidShaderKind, ValidSpvCode) {
704
const ShaderKindTestCase& test_case = GetParam();
705
shaderc::Compiler compiler;
706
EXPECT_TRUE(
707
CompilesToValidSpv(compiler, test_case.shader_, test_case.shader_kind_));
708
}
709
710
INSTANTIATE_TEST_SUITE_P(
711
CompileStringTest, ValidShaderKind,
712
testing::ValuesIn(std::vector<ShaderKindTestCase>{
713
// Valid default shader kinds.
714
{kEmpty310ESShader, shaderc_glsl_default_vertex_shader},
715
{kEmpty310ESShader, shaderc_glsl_default_fragment_shader},
716
{kEmpty310ESShader, shaderc_glsl_default_compute_shader},
717
{kGeometryOnlyShader, shaderc_glsl_default_geometry_shader},
718
{kTessControlOnlyShader, shaderc_glsl_default_tess_control_shader},
719
{kTessEvaluationOnlyShader,
720
shaderc_glsl_default_tess_evaluation_shader},
721
722
// #pragma annotation overrides default shader kinds.
723
{kVertexOnlyShaderWithPragma, shaderc_glsl_default_compute_shader},
724
{kFragmentOnlyShaderWithPragma, shaderc_glsl_default_vertex_shader},
725
{kTessControlOnlyShaderWithPragma,
726
shaderc_glsl_default_fragment_shader},
727
{kTessEvaluationOnlyShaderWithPragma,
728
shaderc_glsl_default_tess_control_shader},
729
{kGeometryOnlyShaderWithPragma,
730
shaderc_glsl_default_tess_evaluation_shader},
731
{kComputeOnlyShaderWithPragma, shaderc_glsl_default_geometry_shader},
732
733
// Specified non-default shader kind overrides #pragma annotation.
734
{kVertexOnlyShaderWithInvalidPragma, shaderc_glsl_vertex_shader},
735
}));
736
737
// Invalid shader kind settings should generate errors.
738
using InvalidShaderKind = testing::TestWithParam<ShaderKindTestCase>;
739
740
TEST_P(InvalidShaderKind, CompilationShouldFail) {
741
const ShaderKindTestCase& test_case = GetParam();
742
shaderc::Compiler compiler;
743
EXPECT_FALSE(
744
CompilesToValidSpv(compiler, test_case.shader_, test_case.shader_kind_));
745
}
746
747
INSTANTIATE_TEST_SUITE_P(
748
CompileStringTest, InvalidShaderKind,
749
testing::ValuesIn(std::vector<ShaderKindTestCase>{
750
// Invalid default shader kind.
751
{kVertexOnlyShader, shaderc_glsl_default_fragment_shader},
752
// Sets to deduce shader kind from #pragma, but #pragma is defined in
753
// the source code.
754
{kVertexOnlyShader, shaderc_glsl_infer_from_source},
755
// Invalid #pragma cause errors, even though default shader kind is set
756
// to valid shader kind.
757
{kVertexOnlyShaderWithInvalidPragma,
758
shaderc_glsl_default_vertex_shader},
759
}));
760
761
// To test file inclusion, use an unordered_map as a fake file system to store
762
// fake files to be included. The unordered_map represents a filesystem by
763
// mapping filename (or path) string to the contents of that file as a string.
764
using FakeFS = std::unordered_map<std::string, std::string>;
765
766
// An includer test case needs: 1) A fake file system which is actually an
767
// unordered_map, so that we can resolve the content given a string. A valid
768
// fake file system must have one entry with key:'root' to specify the start
769
// shader file for compilation. 2) An string that we expect to see in the
770
// compilation output.
771
class IncluderTestCase {
772
public:
773
IncluderTestCase(FakeFS fake_fs, std::string expected_substring)
774
: fake_fs_(fake_fs), expected_substring_(expected_substring) {
775
assert(fake_fs_.find("root") != fake_fs_.end() &&
776
"Valid fake file system needs a 'root' file\n");
777
}
778
779
const FakeFS& fake_fs() const { return fake_fs_; }
780
const std::string& expected_substring() const { return expected_substring_; }
781
782
private:
783
FakeFS fake_fs_;
784
std::string expected_substring_;
785
};
786
787
// A mock class that simulates an includer. This class implements
788
// IncluderInterface to provide GetInclude() and ReleaseInclude() methods.
789
class TestIncluder : public shaderc::CompileOptions::IncluderInterface {
790
public:
791
explicit TestIncluder(const FakeFS& fake_fs)
792
: fake_fs_(fake_fs), responses_({}) {}
793
794
// Get path and content from the fake file system.
795
shaderc_include_result* GetInclude(const char* requested_source,
796
shaderc_include_type type,
797
const char* requesting_source,
798
size_t include_depth) override {
799
responses_.emplace_back(shaderc_include_result{
800
requested_source, strlen(requested_source),
801
fake_fs_.at(std::string(requested_source)).c_str(),
802
fake_fs_.at(std::string(requested_source)).size()});
803
return &responses_.back();
804
}
805
806
// Response data is owned as private property, no need to release explicitly.
807
void ReleaseInclude(shaderc_include_result*) override {}
808
809
private:
810
const FakeFS& fake_fs_;
811
std::vector<shaderc_include_result> responses_;
812
};
813
814
using IncluderTests = testing::TestWithParam<IncluderTestCase>;
815
816
// Parameterized tests for includer.
817
TEST_P(IncluderTests, SetIncluder) {
818
const IncluderTestCase& test_case = GetParam();
819
const FakeFS& fs = test_case.fake_fs();
820
const std::string& shader = fs.at("root");
821
shaderc::Compiler compiler;
822
CompileOptions options;
823
options.SetIncluder(std::unique_ptr<TestIncluder>(new TestIncluder(fs)));
824
const auto compilation_result = compiler.PreprocessGlsl(
825
shader.c_str(), shaderc_glsl_vertex_shader, "shader", options);
826
// Checks the existence of the expected string.
827
EXPECT_THAT(CompilerOutputAsString(compilation_result),
828
HasSubstr(test_case.expected_substring()));
829
}
830
831
TEST_P(IncluderTests, SetIncluderClonedOptions) {
832
const IncluderTestCase& test_case = GetParam();
833
const FakeFS& fs = test_case.fake_fs();
834
const std::string& shader = fs.at("root");
835
shaderc::Compiler compiler;
836
CompileOptions options;
837
options.SetIncluder(std::unique_ptr<TestIncluder>(new TestIncluder(fs)));
838
839
// Cloned options should have all the settings.
840
CompileOptions cloned_options(options);
841
const auto compilation_result = compiler.PreprocessGlsl(
842
shader.c_str(), shaderc_glsl_vertex_shader, "shader", cloned_options);
843
// Checks the existence of the expected string.
844
EXPECT_THAT(CompilerOutputAsString(compilation_result),
845
HasSubstr(test_case.expected_substring()));
846
}
847
848
INSTANTIATE_TEST_SUITE_P(CppInterface, IncluderTests,
849
testing::ValuesIn(std::vector<IncluderTestCase>{
850
IncluderTestCase(
851
// Fake file system.
852
{
853
{"root",
854
"#version 150\n"
855
"void foo() {}\n"
856
"#include \"path/to/file_1\"\n"},
857
{"path/to/file_1", "content of file_1\n"},
858
},
859
// Expected output.
860
"#line 0 \"path/to/file_1\"\n"
861
" content of file_1\n"
862
"#line 3"),
863
IncluderTestCase(
864
// Fake file system.
865
{{"root",
866
"#version 150\n"
867
"void foo() {}\n"
868
"#include \"path/to/file_1\"\n"},
869
{"path/to/file_1",
870
"#include \"path/to/file_2\"\n"
871
"content of file_1\n"},
872
{"path/to/file_2", "content of file_2\n"}},
873
// Expected output.
874
"#line 0 \"path/to/file_1\"\n"
875
"#line 0 \"path/to/file_2\"\n"
876
" content of file_2\n"
877
"#line 1 \"path/to/file_1\"\n"
878
" content of file_1\n"
879
"#line 3"),
880
881
}));
882
883
TEST_F(CppInterface, WarningsOnLine) {
884
// By default the compiler will emit a warning on line 2 complaining
885
// that 'float' is a deprecated attribute in version 130.
886
EXPECT_THAT(
887
CompilationWarnings(kDeprecatedAttributeShader,
888
shaderc_glsl_vertex_shader, CompileOptions()),
889
HasSubstr(":2: warning: attribute deprecated in version 130; may be "
890
"removed in future release\n"));
891
}
892
893
TEST_F(CppInterface, SuppressWarningsOnLine) {
894
// Sets the compiler to suppress warnings, so that the deprecated attribute
895
// warning won't be emitted.
896
options_.SetSuppressWarnings();
897
EXPECT_EQ("", CompilationWarnings(kDeprecatedAttributeShader,
898
shaderc_glsl_vertex_shader, options_));
899
}
900
901
TEST_F(CppInterface, SuppressWarningsOnLineClonedOptions) {
902
// Sets the compiler to suppress warnings, so that the deprecated attribute
903
// warning won't be emitted, and the mode should be carried into any clone of
904
// the original option object.
905
options_.SetSuppressWarnings();
906
CompileOptions cloned_options(options_);
907
EXPECT_EQ("",
908
CompilationWarnings(kDeprecatedAttributeShader,
909
shaderc_glsl_vertex_shader, cloned_options));
910
}
911
912
TEST_F(CppInterface, WarningsOnLineAsErrors) {
913
// Sets the compiler to make warnings into errors. So that the deprecated
914
// attribute warning will be emitted as an error and compilation should fail.
915
options_.SetWarningsAsErrors();
916
EXPECT_THAT(
917
CompilationErrors(kDeprecatedAttributeShader, shaderc_glsl_vertex_shader,
918
options_),
919
HasSubstr(":2: error: attribute deprecated in version 130; may be "
920
"removed in future release\n"));
921
}
922
923
TEST_F(CppInterface, WarningsOnLineAsErrorsClonedOptions) {
924
// Sets the compiler to make warnings into errors. So that the deprecated
925
// attribute warning will be emitted as an error and compilation should fail.
926
options_.SetWarningsAsErrors();
927
CompileOptions cloned_options(options_);
928
// The error message should show an error instead of a warning.
929
EXPECT_THAT(
930
CompilationErrors(kDeprecatedAttributeShader, shaderc_glsl_vertex_shader,
931
cloned_options),
932
HasSubstr(":2: error: attribute deprecated in version 130; may be "
933
"removed in future release\n"));
934
}
935
936
TEST_F(CppInterface, GlobalWarnings) {
937
// By default the compiler will emit a warning as version 550 is an unknown
938
// version.
939
options_.SetForcedVersionProfile(400, shaderc_profile_core);
940
EXPECT_THAT(CompilationWarnings(kMinimalUnknownVersionShader,
941
shaderc_glsl_vertex_shader, options_),
942
HasSubstr("(version, profile) forced to be (400, core),"
943
" while in source code it is (550, none)\n"));
944
}
945
946
TEST_F(CppInterface, SuppressGlobalWarnings) {
947
// Sets the compiler to suppress warnings, so that the unknown version warning
948
// won't be emitted.
949
options_.SetSuppressWarnings();
950
options_.SetForcedVersionProfile(400, shaderc_profile_core);
951
EXPECT_THAT(CompilationWarnings(kMinimalUnknownVersionShader,
952
shaderc_glsl_vertex_shader, options_),
953
Eq(""));
954
}
955
956
TEST_F(CppInterface, SuppressGlobalWarningsClonedOptions) {
957
// Sets the compiler to suppress warnings, so that the unknown version warning
958
// won't be emitted, and the mode should be carried into any clone of the
959
// original option object.
960
options_.SetSuppressWarnings();
961
options_.SetForcedVersionProfile(400, shaderc_profile_core);
962
CompileOptions cloned_options(options_);
963
EXPECT_THAT(CompilationWarnings(kMinimalUnknownVersionShader,
964
shaderc_glsl_vertex_shader, cloned_options),
965
Eq(""));
966
}
967
968
TEST_F(CppInterface, GlobalWarningsAsErrors) {
969
// Sets the compiler to make warnings into errors. So that the unknown
970
// version warning will be emitted as an error and compilation should fail.
971
options_.SetWarningsAsErrors();
972
options_.SetForcedVersionProfile(400, shaderc_profile_core);
973
EXPECT_THAT(CompilationErrors(kMinimalUnknownVersionShader,
974
shaderc_glsl_vertex_shader, options_),
975
HasSubstr("(version, profile) forced to be (400, core),"
976
" while in source code it is (550, none)\n"));
977
}
978
979
TEST_F(CppInterface, GlobalWarningsAsErrorsClonedOptions) {
980
// Sets the compiler to make warnings into errors. This mode should be carried
981
// into any clone of the original option object.
982
options_.SetWarningsAsErrors();
983
options_.SetForcedVersionProfile(400, shaderc_profile_core);
984
CompileOptions cloned_options(options_);
985
EXPECT_THAT(CompilationErrors(kMinimalUnknownVersionShader,
986
shaderc_glsl_vertex_shader, cloned_options),
987
HasSubstr("(version, profile) forced to be (400, core),"
988
" while in source code it is (550, none)\n"));
989
}
990
991
TEST_F(CppInterface, SuppressWarningsModeFirstOverridesWarningsAsErrorsMode) {
992
// Sets suppress-warnings mode first, then sets warnings-as-errors mode.
993
// suppress-warnings mode should override warnings-as-errors mode, no
994
// error message should be output for this case.
995
options_.SetSuppressWarnings();
996
options_.SetWarningsAsErrors();
997
// Warnings on line should be inhibited.
998
EXPECT_EQ("", CompilationWarnings(kDeprecatedAttributeShader,
999
shaderc_glsl_vertex_shader, options_));
1000
1001
// Global warnings should be inhibited.
1002
// However, the unknown version will cause an error.
1003
EXPECT_THAT(CompilationErrors(kMinimalUnknownVersionShader,
1004
shaderc_glsl_vertex_shader, options_),
1005
Eq("shader: error: version not supported\n"));
1006
}
1007
1008
TEST_F(CppInterface, SuppressWarningsModeSecondOverridesWarningsAsErrorsMode) {
1009
// Sets warnings-as-errors mode first, then sets suppress-warnings mode.
1010
// suppress-warnings mode should override warnings-as-errors mode, no
1011
// error message should be output for this case.
1012
options_.SetWarningsAsErrors();
1013
options_.SetSuppressWarnings();
1014
// Warnings on line should be inhibited.
1015
EXPECT_EQ("", CompilationWarnings(kDeprecatedAttributeShader,
1016
shaderc_glsl_vertex_shader, options_));
1017
1018
// Global warnings should be inhibited.
1019
// However, the unknown version will cause an error.
1020
EXPECT_THAT(CompilationErrors(kMinimalUnknownVersionShader,
1021
shaderc_glsl_vertex_shader, options_),
1022
Eq("shader: error: version not supported\n"));
1023
}
1024
1025
TEST_F(CppInterface, TargetEnvCompileOptionsOpenGLCompatibilityShadersFail) {
1026
// Glslang does not support SPIR-V code generation for OpenGL compatibility
1027
// profile.
1028
options_.SetTargetEnvironment(shaderc_target_env_opengl_compat, 0);
1029
const std::string kGlslShader =
1030
R"(#version 150 compatibility
1031
uniform highp sampler2D tex;
1032
void main() {
1033
gl_FragColor = texture2D(tex, vec2(0.0,0.0));
1034
}
1035
)";
1036
1037
const auto errors =
1038
CompilationErrors(kGlslShader, shaderc_glsl_fragment_shader, options_);
1039
EXPECT_EQ(errors, "error: OpenGL compatibility profile is not supported");
1040
}
1041
1042
std::string BarrierComputeShader() {
1043
return R"(#version 450
1044
void main() { barrier(); })";
1045
}
1046
1047
std::string SubgroupBarrierComputeShader() {
1048
return R"(#version 450
1049
#extension GL_KHR_shader_subgroup_basic : enable
1050
void main() { subgroupBarrier(); })";
1051
}
1052
1053
TEST_F(CppInterface, TargetEnvCompileOptionsVulkanEnvVulkan1_0ShaderSucceeds) {
1054
options_.SetTargetEnvironment(shaderc_target_env_vulkan, 0);
1055
EXPECT_TRUE(CompilationSuccess(BarrierComputeShader(),
1056
shaderc_glsl_compute_shader, options_));
1057
}
1058
1059
TEST_F(CppInterface, TargetEnvCompileOptionsVulkanEnvVulkan1_0ShaderFails) {
1060
options_.SetTargetEnvironment(shaderc_target_env_vulkan, 0);
1061
EXPECT_FALSE(CompilationSuccess(SubgroupBarrierComputeShader(),
1062
shaderc_glsl_compute_shader, options_));
1063
}
1064
1065
TEST_F(CppInterface,
1066
TargetEnvCompileOptionsVulkan1_0EnvVulkan1_0ShaderSucceeds) {
1067
options_.SetTargetEnvironment(shaderc_target_env_vulkan,
1068
shaderc_env_version_vulkan_1_0);
1069
EXPECT_TRUE(CompilationSuccess(BarrierComputeShader(),
1070
shaderc_glsl_compute_shader, options_));
1071
}
1072
1073
TEST_F(CppInterface, TargetEnvCompileOptionsVulkan1_0EnvVulkan1_1ShaderFails) {
1074
options_.SetTargetEnvironment(shaderc_target_env_vulkan,
1075
shaderc_env_version_vulkan_1_0);
1076
EXPECT_FALSE(CompilationSuccess(SubgroupBarrierComputeShader(),
1077
shaderc_glsl_compute_shader, options_));
1078
}
1079
1080
TEST_F(CppInterface,
1081
TargetEnvCompileOptionsVulkan1_1EnvVulkan1_0ShaderSucceeds) {
1082
options_.SetTargetEnvironment(shaderc_target_env_vulkan,
1083
shaderc_env_version_vulkan_1_1);
1084
EXPECT_TRUE(CompilationSuccess(BarrierComputeShader(),
1085
shaderc_glsl_compute_shader, options_));
1086
}
1087
1088
TEST_F(CppInterface,
1089
TargetEnvCompileOptionsVulkan1_1EnvVulkan1_1ShaderSucceeds) {
1090
options_.SetTargetEnvironment(shaderc_target_env_vulkan,
1091
shaderc_env_version_vulkan_1_1);
1092
EXPECT_TRUE(CompilationSuccess(SubgroupBarrierComputeShader(),
1093
shaderc_glsl_compute_shader, options_));
1094
}
1095
1096
TEST_F(CppInterface, BeginAndEndOnSpvCompilationResult) {
1097
const SpvCompilationResult compilation_result = compiler_.CompileGlslToSpv(
1098
kMinimalShader, shaderc_glsl_vertex_shader, "shader");
1099
EXPECT_TRUE(IsValidSpv(compilation_result));
1100
// Use range-based for to exercise begin() and end().
1101
std::vector<uint32_t> binary_words;
1102
for (const auto& element : compilation_result) {
1103
binary_words.push_back(element);
1104
}
1105
EXPECT_THAT(binary_words,
1106
Eq(std::vector<uint32_t>(compilation_result.cbegin(),
1107
compilation_result.cend())));
1108
}
1109
1110
TEST_F(CppInterface, BeginAndEndOnAssemblyCompilationResult) {
1111
const AssemblyCompilationResult compilation_result =
1112
compiler_.CompileGlslToSpvAssembly(
1113
kMinimalShader, shaderc_glsl_vertex_shader, "shader", options_);
1114
const std::string forced_to_be_a_string =
1115
CompilerOutputAsString(compilation_result);
1116
EXPECT_THAT(forced_to_be_a_string, HasSubstr("MemoryModel"));
1117
const std::string string_via_begin_end(compilation_result.begin(),
1118
compilation_result.end());
1119
EXPECT_THAT(string_via_begin_end, Eq(forced_to_be_a_string));
1120
}
1121
1122
TEST_F(CppInterface, BeginAndEndOnPreprocessedResult) {
1123
const PreprocessedSourceCompilationResult compilation_result =
1124
compiler_.PreprocessGlsl(kMinimalShader, shaderc_glsl_vertex_shader,
1125
"shader", options_);
1126
const std::string forced_to_be_a_string =
1127
CompilerOutputAsString(compilation_result);
1128
EXPECT_THAT(forced_to_be_a_string, HasSubstr("void main()"));
1129
const std::string string_via_begin_end(compilation_result.begin(),
1130
compilation_result.end());
1131
EXPECT_THAT(string_via_begin_end, Eq(forced_to_be_a_string));
1132
}
1133
1134
TEST_F(CppInterface, SourceLangGlslMinimalGlslVertexShaderSucceeds) {
1135
options_.SetSourceLanguage(shaderc_source_language_glsl);
1136
EXPECT_TRUE(CompilationSuccess(kVertexOnlyShader, shaderc_glsl_vertex_shader,
1137
options_));
1138
}
1139
1140
TEST_F(CppInterface, SourceLangGlslMinimalHlslVertexShaderFails) {
1141
options_.SetSourceLanguage(shaderc_source_language_glsl);
1142
EXPECT_FALSE(CompilationSuccess(kMinimalHlslShader,
1143
shaderc_glsl_vertex_shader, options_));
1144
}
1145
1146
TEST_F(CppInterface, SourceLangHlslMinimalGlslVertexShaderFails) {
1147
options_.SetSourceLanguage(shaderc_source_language_hlsl);
1148
EXPECT_FALSE(CompilationSuccess(kVertexOnlyShader, shaderc_glsl_vertex_shader,
1149
options_));
1150
}
1151
1152
TEST_F(CppInterface, SourceLangHlslMinimalHlslVertexShaderSucceeds) {
1153
options_.SetSourceLanguage(shaderc_source_language_hlsl);
1154
EXPECT_TRUE(CompilationSuccess(kMinimalHlslShader, shaderc_glsl_vertex_shader,
1155
options_));
1156
}
1157
1158
TEST(
1159
EntryPointTest,
1160
SourceLangHlslMinimalHlslVertexShaderAsConstCharPtrSucceedsWithEntryPointName) {
1161
shaderc::Compiler compiler;
1162
CompileOptions options;
1163
options.SetSourceLanguage(shaderc_source_language_hlsl);
1164
auto result = compiler.CompileGlslToSpv(
1165
kMinimalHlslShader, strlen(kMinimalHlslShader),
1166
shaderc_glsl_vertex_shader, "shader", "EntryPoint", options);
1167
std::vector<uint32_t> binary(result.begin(), result.end());
1168
std::string assembly;
1169
spvtools::SpirvTools(SPV_ENV_UNIVERSAL_1_0).Disassemble(binary, &assembly);
1170
EXPECT_THAT(assembly,
1171
HasSubstr("OpEntryPoint Vertex %EntryPoint \"EntryPoint\""))
1172
<< assembly;
1173
}
1174
1175
TEST(
1176
EntryPointTest,
1177
SourceLangHlslMinimalHlslVertexShaderAsStdStringSucceedsWithEntryPointName) {
1178
shaderc::Compiler compiler;
1179
CompileOptions options;
1180
options.SetSourceLanguage(shaderc_source_language_hlsl);
1181
std::string shader(kMinimalHlslShader);
1182
auto result = compiler.CompileGlslToSpv(shader, shaderc_glsl_vertex_shader,
1183
"shader", "EntryPoint", options);
1184
std::vector<uint32_t> binary(result.begin(), result.end());
1185
std::string assembly;
1186
spvtools::SpirvTools(SPV_ENV_UNIVERSAL_1_0).Disassemble(binary, &assembly);
1187
EXPECT_THAT(assembly,
1188
HasSubstr("OpEntryPoint Vertex %EntryPoint \"EntryPoint\""))
1189
<< assembly;
1190
}
1191
1192
TEST(
1193
EntryPointTest,
1194
SourceLangHlslMinimalHlslVertexShaderAsConstCharPtrSucceedsToAssemblyWithEntryPointName) {
1195
shaderc::Compiler compiler;
1196
CompileOptions options;
1197
options.SetSourceLanguage(shaderc_source_language_hlsl);
1198
auto assembly = compiler.CompileGlslToSpvAssembly(
1199
kMinimalHlslShader, strlen(kMinimalHlslShader),
1200
shaderc_glsl_vertex_shader, "shader", "EntryPoint", options);
1201
EXPECT_THAT(std::string(assembly.begin(), assembly.end()),
1202
HasSubstr("OpEntryPoint Vertex %EntryPoint \"EntryPoint\""));
1203
}
1204
1205
TEST(
1206
EntryPointTest,
1207
SourceLangHlslMinimalHlslVertexShaderAsStdStringSucceedsToAssemblyWithEntryPointName) {
1208
shaderc::Compiler compiler;
1209
CompileOptions options;
1210
options.SetSourceLanguage(shaderc_source_language_hlsl);
1211
std::string shader(kMinimalHlslShader);
1212
auto assembly = compiler.CompileGlslToSpvAssembly(
1213
shader, shaderc_glsl_vertex_shader, "shader", "EntryPoint", options);
1214
EXPECT_THAT(std::string(assembly.begin(), assembly.end()),
1215
HasSubstr("OpEntryPoint Vertex %EntryPoint \"EntryPoint\""));
1216
}
1217
1218
// Returns a fragment shader accessing a texture with the given
1219
// offset.
1220
std::string ShaderWithTexOffset(int offset) {
1221
std::ostringstream oss;
1222
oss << "#version 450\n"
1223
"layout (binding=0) uniform sampler1D tex;\n"
1224
"void main() { vec4 x = textureOffset(tex, 1.0, "
1225
<< offset << "); }\n";
1226
return oss.str();
1227
}
1228
1229
// Ensure compilation is sensitive to limit setting. Sample just
1230
// two particular limits.
1231
TEST_F(CppInterface, LimitsTexelOffsetDefault) {
1232
EXPECT_FALSE(CompilationSuccess(ShaderWithTexOffset(-9).c_str(),
1233
shaderc_glsl_fragment_shader, options_));
1234
EXPECT_TRUE(CompilationSuccess(ShaderWithTexOffset(-8).c_str(),
1235
shaderc_glsl_fragment_shader, options_));
1236
EXPECT_TRUE(CompilationSuccess(ShaderWithTexOffset(7).c_str(),
1237
shaderc_glsl_fragment_shader, options_));
1238
EXPECT_FALSE(CompilationSuccess(ShaderWithTexOffset(8).c_str(),
1239
shaderc_glsl_fragment_shader, options_));
1240
}
1241
1242
TEST_F(CppInterface, LimitsTexelOffsetLowerMinimum) {
1243
options_.SetLimit(shaderc_limit_min_program_texel_offset, -99);
1244
EXPECT_FALSE(CompilationSuccess(ShaderWithTexOffset(-100).c_str(),
1245
shaderc_glsl_fragment_shader, options_));
1246
EXPECT_TRUE(CompilationSuccess(ShaderWithTexOffset(-99).c_str(),
1247
shaderc_glsl_fragment_shader, options_));
1248
}
1249
1250
TEST_F(CppInterface, LimitsTexelOffsetHigherMaximum) {
1251
options_.SetLimit(shaderc_limit_max_program_texel_offset, 10);
1252
EXPECT_TRUE(CompilationSuccess(ShaderWithTexOffset(10).c_str(),
1253
shaderc_glsl_fragment_shader, options_));
1254
EXPECT_FALSE(CompilationSuccess(ShaderWithTexOffset(11).c_str(),
1255
shaderc_glsl_fragment_shader, options_));
1256
}
1257
1258
TEST_F(CppInterface, UniformsWithoutBindingsFailCompilation) {
1259
CompileOptions options;
1260
const std::string errors = CompilationErrors(
1261
kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader, options);
1262
EXPECT_THAT(errors,
1263
HasSubstr("sampler/texture/image requires layout(binding=X)"));
1264
}
1265
1266
TEST_F(CppInterface,
1267
UniformsWithoutBindingsOptionSetAutoBindingsAssignsBindings) {
1268
CompileOptions options;
1269
options.SetAutoBindUniforms(true);
1270
const std::string disassembly_text = AssemblyOutput(
1271
kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader, options);
1272
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
1273
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 1"));
1274
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 2"));
1275
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 3"));
1276
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 4"));
1277
}
1278
1279
TEST_F(CppInterface, SetBindingBaseForTextureAdjustsTextureBindingsOnly) {
1280
CompileOptions options;
1281
options.SetAutoBindUniforms(true);
1282
options.SetBindingBase(shaderc_uniform_kind_texture, 44);
1283
const std::string disassembly_text = AssemblyOutput(
1284
kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader, options);
1285
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 44"));
1286
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 0"));
1287
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 1"));
1288
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 2"));
1289
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 3"));
1290
}
1291
1292
TEST_F(CppInterface, SetBindingBaseForSamplerAdjustsSamplerBindingsOnly) {
1293
CompileOptions options;
1294
options.SetAutoBindUniforms(true);
1295
options.SetBindingBase(shaderc_uniform_kind_sampler, 44);
1296
const std::string disassembly_text = AssemblyOutput(
1297
kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader, options);
1298
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
1299
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 44"));
1300
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 1"));
1301
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 2"));
1302
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 3"));
1303
}
1304
1305
TEST_F(CppInterface, SetBindingBaseForImageAdjustsImageBindingsOnly) {
1306
CompileOptions options;
1307
options.SetAutoBindUniforms(true);
1308
options.SetBindingBase(shaderc_uniform_kind_image, 44);
1309
const std::string disassembly_text = AssemblyOutput(
1310
kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader, options);
1311
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
1312
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 1"));
1313
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 44"));
1314
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 45"));
1315
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 2"));
1316
}
1317
1318
TEST_F(CppInterface, SetBindingBaseForBufferAdjustsBufferBindingsOnly) {
1319
CompileOptions options;
1320
options.SetAutoBindUniforms(true);
1321
options.SetBindingBase(shaderc_uniform_kind_buffer, 44);
1322
const std::string disassembly_text = AssemblyOutput(
1323
kShaderWithUniformsWithoutBindings, shaderc_glsl_vertex_shader, options);
1324
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 0"));
1325
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 1"));
1326
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 2"));
1327
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 3"));
1328
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 44"));
1329
}
1330
1331
TEST_F(CppInterface, SetBindingBaseSurvivesCloning) {
1332
CompileOptions options;
1333
options.SetAutoBindUniforms(true);
1334
options.SetBindingBase(shaderc_uniform_kind_texture, 40);
1335
options.SetBindingBase(shaderc_uniform_kind_sampler, 50);
1336
options.SetBindingBase(shaderc_uniform_kind_image, 60);
1337
options.SetBindingBase(shaderc_uniform_kind_buffer, 70);
1338
CompileOptions cloned_options(options);
1339
const std::string disassembly_text =
1340
AssemblyOutput(kShaderWithUniformsWithoutBindings,
1341
shaderc_glsl_vertex_shader, cloned_options);
1342
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_tex Binding 40"));
1343
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_sam Binding 50"));
1344
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_img Binding 60"));
1345
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_imbuf Binding 61"));
1346
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %my_ubo Binding 70"));
1347
}
1348
1349
TEST_F(CppInterface, GlslDefaultPackingUsed) {
1350
CompileOptions options;
1351
const std::string disassembly_text = AssemblyOutput(
1352
kGlslShaderWeirdPacking, shaderc_glsl_vertex_shader, options);
1353
EXPECT_THAT(disassembly_text, HasSubstr("OpMemberDecorate %B 1 Offset 16"));
1354
}
1355
1356
TEST_F(CppInterface, HlslOffsetsOptionDisableRespected) {
1357
CompileOptions options;
1358
options.SetHlslOffsets(false);
1359
const std::string disassembly_text = AssemblyOutput(
1360
kGlslShaderWeirdPacking, shaderc_glsl_vertex_shader, options);
1361
EXPECT_THAT(disassembly_text, HasSubstr("OpMemberDecorate %B 1 Offset 16"));
1362
}
1363
1364
TEST_F(CppInterface, HlslOffsetsOptionEnableRespected) {
1365
CompileOptions options;
1366
options.SetHlslOffsets(true);
1367
const std::string disassembly_text = AssemblyOutput(
1368
kGlslShaderWeirdPacking, shaderc_glsl_vertex_shader, options);
1369
EXPECT_THAT(disassembly_text, HasSubstr("OpMemberDecorate %B 1 Offset 4"));
1370
}
1371
1372
TEST_F(CppInterface, HlslRegSetBindingForFragmentRespected) {
1373
CompileOptions options;
1374
options.SetSourceLanguage(shaderc_source_language_hlsl);
1375
options.SetHlslRegisterSetAndBindingForStage(shaderc_fragment_shader, "t4",
1376
"9", "16");
1377
const std::string disassembly_text = AssemblyOutput(
1378
kHlslFragShaderWithRegisters, shaderc_glsl_fragment_shader, options);
1379
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %t4 DescriptorSet 9"));
1380
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %t4 Binding 16"));
1381
}
1382
1383
TEST_F(CppInterface, HlslRegSetBindingForDifferentStageIgnored) {
1384
CompileOptions options;
1385
options.SetSourceLanguage(shaderc_source_language_hlsl);
1386
options.SetHlslRegisterSetAndBindingForStage(shaderc_vertex_shader, "t4", "9",
1387
"16");
1388
const std::string disassembly_text = AssemblyOutput(
1389
kHlslFragShaderWithRegisters, shaderc_glsl_fragment_shader, options);
1390
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %t4 DescriptorSet 0"));
1391
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %t4 Binding 4"));
1392
}
1393
1394
TEST_F(CppInterface, HlslRegSetBindingForAllStagesRespected) {
1395
CompileOptions options;
1396
options.SetSourceLanguage(shaderc_source_language_hlsl);
1397
options.SetHlslRegisterSetAndBinding("t4", "9", "16");
1398
const std::string disassembly_text = AssemblyOutput(
1399
kHlslFragShaderWithRegisters, shaderc_glsl_fragment_shader, options);
1400
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %t4 DescriptorSet 9"));
1401
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorate %t4 Binding 16"));
1402
}
1403
1404
TEST_F(CppInterface, HlslFunctionality1OffByDefault) {
1405
CompileOptions options;
1406
options.SetSourceLanguage(shaderc_source_language_hlsl);
1407
// The counter needs a binding, and there is no way to set it in the shader
1408
// source.
1409
options.SetAutoBindUniforms(true);
1410
const std::string disassembly_text = AssemblyOutput(
1411
kHlslShaderWithCounterBuffer, shaderc_glsl_fragment_shader, options);
1412
EXPECT_THAT(disassembly_text, Not(HasSubstr("OpDecorateString")));
1413
}
1414
1415
TEST_F(CppInterface, HlslFunctionality1Respected) {
1416
CompileOptions options;
1417
options.SetSourceLanguage(shaderc_source_language_hlsl);
1418
// The counter needs a binding, and there is no way to set it in the shader
1419
// source. https://github.com/KhronosGroup/glslang/issues/1616
1420
options.SetAutoBindUniforms(true);
1421
options.SetHlslFunctionality1(true);
1422
const std::string disassembly_text = AssemblyOutput(
1423
kHlslShaderWithCounterBuffer, shaderc_glsl_fragment_shader, options);
1424
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorateString"));
1425
}
1426
1427
TEST_F(CppInterface, HlslFunctionality1SurvivesCloning) {
1428
CompileOptions options;
1429
options.SetSourceLanguage(shaderc_source_language_hlsl);
1430
options.SetHlslFunctionality1(true);
1431
// The counter needs a binding, and there is no way to set it in the shader
1432
// source. https://github.com/KhronosGroup/glslang/issues/1616
1433
options.SetAutoBindUniforms(true);
1434
CompileOptions cloned_options(options);
1435
const std::string disassembly_text = AssemblyOutput(
1436
kHlslShaderWithCounterBuffer, shaderc_glsl_fragment_shader, cloned_options);
1437
EXPECT_THAT(disassembly_text, HasSubstr("OpDecorateString"));
1438
}
1439
1440
TEST_F(CppInterface, NanClampDefaultsOff) {
1441
CompileOptions options;
1442
const std::string disassembly_text = AssemblyOutput(
1443
kGlslShaderWithClamp, shaderc_glsl_fragment_shader, options);
1444
EXPECT_THAT(disassembly_text, HasSubstr("OpExtInst %v4float %1 FClamp"));
1445
}
1446
1447
TEST_F(CppInterface, NanClampMapsClampToNClamp) {
1448
CompileOptions options;
1449
options.SetNanClamp(true);
1450
const std::string disassembly_text = AssemblyOutput(
1451
kGlslShaderWithClamp, shaderc_glsl_fragment_shader, options);
1452
EXPECT_THAT(disassembly_text, HasSubstr("OpExtInst %v4float %1 NClamp"));
1453
}
1454
1455
TEST_F(CppInterface, NanClampSurvivesCloning) {
1456
CompileOptions options;
1457
options.SetNanClamp(true);
1458
CompileOptions cloned_options(options);
1459
const std::string disassembly_text = AssemblyOutput(
1460
kGlslShaderWithClamp, shaderc_glsl_fragment_shader, cloned_options);
1461
EXPECT_THAT(disassembly_text, HasSubstr("OpExtInst %v4float %1 NClamp"));
1462
}
1463
1464
} // anonymous namespace
1465
1466