• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2018 The Android Open Source Project
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 "ShaderUtils.h"
16 
17 #include "aemu/base/files/PathUtils.h"
18 #include "aemu/base/Optional.h"
19 #include "aemu/base/system/System.h"
20 
21 #include "OpenGLESDispatch/OpenGLDispatchLoader.h"
22 
23 #include <fstream>
24 #include <vector>
25 
26 #include <fcntl.h>
27 #include <stdio.h>
28 
29 using android::base::Optional;
30 using android::base::pj;
31 
32 #define DEBUG 0
33 
34 #if DEBUG
35 #define D(fmt,...) fprintf(stderr, "%s: " fmt "\n", __func__, ##__VA_ARGS__);
36 #else
37 #define D(fmt,...)
38 #endif
39 
40 #define E(fmt,...) fprintf(stderr, "%s: " fmt "\n", __func__, ##__VA_ARGS__);
41 
42 namespace gfxstream {
43 
compileShader(GLenum shaderType,const char * src)44 GLuint compileShader(GLenum shaderType, const char* src) {
45     auto gl = gl::LazyLoadedGLESv2Dispatch::get();
46 
47     GLuint shader = gl->glCreateShader(shaderType);
48     gl->glShaderSource(shader, 1, (const GLchar* const*)&src, nullptr);
49     gl->glCompileShader(shader);
50 
51     GLint compileStatus;
52     gl->glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
53 
54     if (compileStatus != GL_TRUE) {
55         GLsizei infoLogLength = 0;
56         gl->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
57         std::vector<char> infoLog(infoLogLength + 1, 0);
58         gl->glGetShaderInfoLog(shader, infoLogLength, nullptr, &infoLog[0]);
59         E("fail to compile. infolog: %s", &infoLog[0]);
60     }
61 
62     return shader;
63 }
64 
compileAndLinkShaderProgram(const char * vshaderSrc,const char * fshaderSrc)65 GLint compileAndLinkShaderProgram(const char* vshaderSrc, const char* fshaderSrc) {
66     auto gl = gl::LazyLoadedGLESv2Dispatch::get();
67 
68     GLuint vshader = compileShader(GL_VERTEX_SHADER, vshaderSrc);
69     GLuint fshader = compileShader(GL_FRAGMENT_SHADER, fshaderSrc);
70 
71     GLuint program = gl->glCreateProgram();
72     gl->glAttachShader(program, vshader);
73     gl->glAttachShader(program, fshader);
74     gl->glLinkProgram(program);
75 
76     GLint linkStatus;
77     gl->glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
78 
79     gl->glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
80 
81     if (linkStatus != GL_TRUE) {
82         GLsizei infoLogLength = 0;
83         gl->glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
84         std::vector<char> infoLog(infoLogLength + 1, 0);
85         gl->glGetProgramInfoLog(program, infoLogLength, nullptr, &infoLog[0]);
86 
87         E("failed to link. infolog: %s", &infoLog[0]);
88     }
89 
90     return program;
91 }
92 
93 // static Optional<std::string> getSpirvCompilerPath() {
94 // #ifdef _WIN32
95 //     std::string programName = "glslangValidator.exe";
96 // #else
97 //     std::string programName = "glslangValidator";
98 // #endif
99 //
100 //     auto programDirRelativePath =
101 //         pj(android::base::getProgramDirectory(),
102 //            "lib64", "vulkan", "tools", programName);
103 //
104 //     if (path_exists(programDirRelativePath.c_str())) {
105 //         return programDirRelativePath;
106 //     }
107 //
108 //     auto launcherDirRelativePath =
109 //         pj(android::base::getLauncherDirectory(),
110 //            "lib64", "vulkan", programName);
111 //
112 //     if (path_exists(launcherDirRelativePath.c_str())) {
113 //         return launcherDirRelativePath;
114 //     }
115 //
116 //     E("spirv compiler does not exist");
117 //     return {};
118 // }
119 
120 // Optional<std::string> compileSpirvFromGLSL(const std::string& shaderType,
121 //                                            const std::string& src) {
122 //     auto spvCompilerPath = getSpirvCompilerPath();
123 //
124 //     if (!spvCompilerPath) return {};
125 //
126 //     const auto glslFile = android::base::makeCustomScopedPtr(
127 //             tempfile_create(), tempfile_unref_and_close_file);
128 //
129 //     const auto spvFile = android::base::makeCustomScopedPtr(
130 //             tempfile_create(), tempfile_unref_and_close_file);
131 //
132 //     auto glslPath = tempfile_path(glslFile.get());
133 //     auto spvPath = tempfile_path(spvFile.get());
134 //
135 //     auto glslFd = android::base::ScopedFd(open(glslPath, O_RDWR));
136 //     if (!glslFd.valid()) { return {}; }
137 //
138 //     android::writeStringToFile(glslFd.get(), src);
139 //     glslFd.close();
140 //
141 //     std::vector<std::string> args =
142 //         { *spvCompilerPath, glslPath, "-V", "-S", shaderType, "-o", spvPath };
143 //
144 //     auto runRes = System::get()->runCommandWithResult(args);
145 //
146 //     if (!runRes) {
147 //         E("failed to compile SPIRV from GLSL. args: %s %s -V -S %s -o %s",
148 //           spvCompilerPath->c_str(), glslPath, shaderType.c_str(), spvPath);
149 //         return {};
150 //     }
151 //
152 //     D("Result of compiling SPIRV from GLSL. res: %s args: %s %s -V -S %s -o %s",
153 //       runRes->c_str(), spvCompilerPath->c_str(), glslPath, shaderType.c_str(),
154 //       spvPath);
155 //
156 //     auto res = android::readFileIntoString(spvPath);
157 //
158 //     if (res) {
159 //         D("got %zu bytes:", res->size());
160 //     } else {
161 //         E("failed to read SPIRV file %s into string", spvPath);
162 //     }
163 //
164 //     return res;
165 // }
166 //
167 // Optional<std::vector<char> > readSpirv(const char* path) {
168 //     std::ifstream in(path, std::ios::ate | std::ios::binary);
169 //
170 //     if (!in) return {};
171 //
172 //     size_t fileSize = (size_t)in.tellg();
173 //     std::vector<char> buffer(fileSize);
174 //
175 //     in.seekg(0);
176 //     in.read(buffer.data(), fileSize);
177 //
178 //     return buffer;
179 // }
180 
181 }  // namespace gfxstream
182