1// Copyright (c) 2019 Google LLC.
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 "test/val/val_code_generator.h"
16
17#include <sstream>
18
19namespace spvtools {
20namespace val {
21namespace {
22
23std::string GetDefaultShaderCapabilities() {
24  return R"(
25OpCapability Shader
26OpCapability Geometry
27OpCapability Tessellation
28OpCapability Float64
29OpCapability Int64
30OpCapability MultiViewport
31OpCapability SampleRateShading
32)";
33}
34
35std::string GetDefaultShaderTypes() {
36  return R"(
37%void = OpTypeVoid
38%func = OpTypeFunction %void
39%bool = OpTypeBool
40%f32 = OpTypeFloat 32
41%f64 = OpTypeFloat 64
42%i32 = OpTypeInt 32 1
43%i64 = OpTypeInt 64 1
44%u32 = OpTypeInt 32 0
45%u64 = OpTypeInt 64 0
46%f32vec2 = OpTypeVector %f32 2
47%f32vec3 = OpTypeVector %f32 3
48%f32vec4 = OpTypeVector %f32 4
49%f64vec2 = OpTypeVector %f64 2
50%f64vec3 = OpTypeVector %f64 3
51%f64vec4 = OpTypeVector %f64 4
52%u32vec2 = OpTypeVector %u32 2
53%u32vec3 = OpTypeVector %u32 3
54%u64vec3 = OpTypeVector %u64 3
55%u32vec4 = OpTypeVector %u32 4
56%u64vec2 = OpTypeVector %u64 2
57
58%f32_0 = OpConstant %f32 0
59%f32_1 = OpConstant %f32 1
60%f32_2 = OpConstant %f32 2
61%f32_3 = OpConstant %f32 3
62%f32_4 = OpConstant %f32 4
63%f32_h = OpConstant %f32 0.5
64%f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
65%f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
66%f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
67%f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
68%f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
69%f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
70
71%f64_0 = OpConstant %f64 0
72%f64_1 = OpConstant %f64 1
73%f64_2 = OpConstant %f64 2
74%f64_3 = OpConstant %f64 3
75%f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
76%f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
77%f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
78
79%u32_0 = OpConstant %u32 0
80%u32_1 = OpConstant %u32 1
81%u32_2 = OpConstant %u32 2
82%u32_3 = OpConstant %u32 3
83%u32_4 = OpConstant %u32 4
84
85%u64_0 = OpConstant %u64 0
86%u64_1 = OpConstant %u64 1
87%u64_2 = OpConstant %u64 2
88%u64_3 = OpConstant %u64 3
89
90%u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
91%u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
92%u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
93%u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1
94
95%u32arr2 = OpTypeArray %u32 %u32_2
96%u32arr3 = OpTypeArray %u32 %u32_3
97%u32arr4 = OpTypeArray %u32 %u32_4
98%u64arr2 = OpTypeArray %u64 %u32_2
99%u64arr3 = OpTypeArray %u64 %u32_3
100%u64arr4 = OpTypeArray %u64 %u32_4
101%f32arr2 = OpTypeArray %f32 %u32_2
102%f32arr3 = OpTypeArray %f32 %u32_3
103%f32arr4 = OpTypeArray %f32 %u32_4
104%f64arr2 = OpTypeArray %f64 %u32_2
105%f64arr3 = OpTypeArray %f64 %u32_3
106%f64arr4 = OpTypeArray %f64 %u32_4
107
108%f32vec3arr3 = OpTypeArray %f32vec3 %u32_3
109%f32vec4arr3 = OpTypeArray %f32vec4 %u32_3
110%f64vec4arr3 = OpTypeArray %f64vec4 %u32_3
111
112%f32mat22 = OpTypeMatrix %f32vec2 2
113%f32mat23 = OpTypeMatrix %f32vec2 3
114%f32mat32 = OpTypeMatrix %f32vec3 2
115%f32mat33 = OpTypeMatrix %f32vec3 3
116%f64mat22 = OpTypeMatrix %f64vec2 2
117%f32mat34 = OpTypeMatrix %f32vec3 4
118%f32mat43 = OpTypeMatrix %f32vec4 3
119%f32mat44 = OpTypeMatrix %f32vec4 4
120)";
121}
122
123}  // namespace
124
125CodeGenerator CodeGenerator::GetDefaultShaderCodeGenerator() {
126  CodeGenerator generator;
127  generator.capabilities_ = GetDefaultShaderCapabilities();
128  generator.memory_model_ = "OpMemoryModel Logical GLSL450\n";
129  generator.types_ = GetDefaultShaderTypes();
130  return generator;
131}
132
133std::string CodeGenerator::Build() const {
134  std::ostringstream ss;
135
136  ss << capabilities_;
137  ss << extensions_;
138  ss << memory_model_;
139
140  for (const EntryPoint& entry_point : entry_points_) {
141    ss << "OpEntryPoint " << entry_point.execution_model << " %"
142       << entry_point.name << " \"" << entry_point.name << "\" "
143       << entry_point.interfaces << "\n";
144  }
145
146  for (const EntryPoint& entry_point : entry_points_) {
147    ss << entry_point.execution_modes << "\n";
148  }
149
150  ss << before_types_;
151  ss << types_;
152  ss << after_types_;
153
154  for (const EntryPoint& entry_point : entry_points_) {
155    ss << "\n";
156    ss << "%" << entry_point.name << " = OpFunction %void None %func\n";
157    ss << "%" << entry_point.name << "_entry = OpLabel\n";
158    ss << entry_point.body;
159    ss << "\nOpReturn\nOpFunctionEnd\n";
160  }
161
162  ss << add_at_the_end_;
163
164  return ss.str();
165}
166
167}  // namespace val
168}  // namespace spvtools
169