blob: fb038ab9e899c5a6e99338b09536f8dac8998a46 [file] [log] [blame]
// Copyright (C) 2018 The Android Open Source Project
//
// 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.
#include "ShaderUtils.h"
#include "aemu/base/files/PathUtils.h"
#include "aemu/base/Optional.h"
#include "aemu/base/system/System.h"
#include "OpenGLESDispatch/OpenGLDispatchLoader.h"
#include <fstream>
#include <vector>
#include <fcntl.h>
#include <stdio.h>
using android::base::Optional;
using android::base::pj;
#define DEBUG 0
#if DEBUG
#define D(fmt,...) fprintf(stderr, "%s: " fmt "\n", __func__, ##__VA_ARGS__);
#else
#define D(fmt,...)
#endif
#define E(fmt,...) fprintf(stderr, "%s: " fmt "\n", __func__, ##__VA_ARGS__);
namespace gfxstream {
GLuint compileShader(GLenum shaderType, const char* src) {
auto gl = gl::LazyLoadedGLESv2Dispatch::get();
GLuint shader = gl->glCreateShader(shaderType);
gl->glShaderSource(shader, 1, (const GLchar* const*)&src, nullptr);
gl->glCompileShader(shader);
GLint compileStatus;
gl->glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
if (compileStatus != GL_TRUE) {
GLsizei infoLogLength = 0;
gl->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
std::vector<char> infoLog(infoLogLength + 1, 0);
gl->glGetShaderInfoLog(shader, infoLogLength, nullptr, &infoLog[0]);
E("fail to compile. infolog: %s", &infoLog[0]);
}
return shader;
}
GLint compileAndLinkShaderProgram(const char* vshaderSrc, const char* fshaderSrc) {
auto gl = gl::LazyLoadedGLESv2Dispatch::get();
GLuint vshader = compileShader(GL_VERTEX_SHADER, vshaderSrc);
GLuint fshader = compileShader(GL_FRAGMENT_SHADER, fshaderSrc);
GLuint program = gl->glCreateProgram();
gl->glAttachShader(program, vshader);
gl->glAttachShader(program, fshader);
gl->glLinkProgram(program);
GLint linkStatus;
gl->glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
gl->glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
if (linkStatus != GL_TRUE) {
GLsizei infoLogLength = 0;
gl->glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
std::vector<char> infoLog(infoLogLength + 1, 0);
gl->glGetProgramInfoLog(program, infoLogLength, nullptr, &infoLog[0]);
E("failed to link. infolog: %s", &infoLog[0]);
}
return program;
}
// static Optional<std::string> getSpirvCompilerPath() {
// #ifdef _WIN32
// std::string programName = "glslangValidator.exe";
// #else
// std::string programName = "glslangValidator";
// #endif
//
// auto programDirRelativePath =
// pj(android::base::getProgramDirectory(),
// "lib64", "vulkan", "tools", programName);
//
// if (path_exists(programDirRelativePath.c_str())) {
// return programDirRelativePath;
// }
//
// auto launcherDirRelativePath =
// pj(android::base::getLauncherDirectory(),
// "lib64", "vulkan", programName);
//
// if (path_exists(launcherDirRelativePath.c_str())) {
// return launcherDirRelativePath;
// }
//
// E("spirv compiler does not exist");
// return {};
// }
// Optional<std::string> compileSpirvFromGLSL(const std::string& shaderType,
// const std::string& src) {
// auto spvCompilerPath = getSpirvCompilerPath();
//
// if (!spvCompilerPath) return {};
//
// const auto glslFile = android::base::makeCustomScopedPtr(
// tempfile_create(), tempfile_unref_and_close_file);
//
// const auto spvFile = android::base::makeCustomScopedPtr(
// tempfile_create(), tempfile_unref_and_close_file);
//
// auto glslPath = tempfile_path(glslFile.get());
// auto spvPath = tempfile_path(spvFile.get());
//
// auto glslFd = android::base::ScopedFd(open(glslPath, O_RDWR));
// if (!glslFd.valid()) { return {}; }
//
// android::writeStringToFile(glslFd.get(), src);
// glslFd.close();
//
// std::vector<std::string> args =
// { *spvCompilerPath, glslPath, "-V", "-S", shaderType, "-o", spvPath };
//
// auto runRes = System::get()->runCommandWithResult(args);
//
// if (!runRes) {
// E("failed to compile SPIRV from GLSL. args: %s %s -V -S %s -o %s",
// spvCompilerPath->c_str(), glslPath, shaderType.c_str(), spvPath);
// return {};
// }
//
// D("Result of compiling SPIRV from GLSL. res: %s args: %s %s -V -S %s -o %s",
// runRes->c_str(), spvCompilerPath->c_str(), glslPath, shaderType.c_str(),
// spvPath);
//
// auto res = android::readFileIntoString(spvPath);
//
// if (res) {
// D("got %zu bytes:", res->size());
// } else {
// E("failed to read SPIRV file %s into string", spvPath);
// }
//
// return res;
// }
//
// Optional<std::vector<char> > readSpirv(const char* path) {
// std::ifstream in(path, std::ios::ate | std::ios::binary);
//
// if (!in) return {};
//
// size_t fileSize = (size_t)in.tellg();
// std::vector<char> buffer(fileSize);
//
// in.seekg(0);
// in.read(buffer.data(), fileSize);
//
// return buffer;
// }
} // namespace gfxstream