blob: a9a9c69d95a910ee4018ec45e11396120a679dfb [file] [log] [blame]
joshualitt30ba4362014-08-21 20:18:45 -07001/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/core/SkAutoMalloc.h"
Brian Osmanac9be9d2019-05-01 10:29:34 -04009#include "src/gpu/GrShaderUtils.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "src/gpu/gl/GrGLGpu.h"
11#include "src/gpu/gl/builders/GrGLShaderStringBuilder.h"
12#include "src/sksl/SkSLCompiler.h"
13#include "src/sksl/SkSLGLSLCodeGenerator.h"
14#include "src/sksl/ir/SkSLProgram.h"
joshualitt30ba4362014-08-21 20:18:45 -070015
halcanary4e44efe2016-08-04 10:47:16 -070016// Print the source code for all shaders generated.
Brian Salomon06ab3832017-12-04 16:45:30 -050017static const bool gPrintSKSL = false;
18static const bool gPrintGLSL = false;
joshualitt30ba4362014-08-21 20:18:45 -070019
Brian Osman79719262020-11-23 14:54:33 -050020std::unique_ptr<SkSL::Program> GrSkSLtoGLSL(const GrGLGpu* gpu,
John Stilesdbd4e6f2021-02-16 13:29:15 -050021 SkSL::ProgramKind programKind,
Brian Osman6c431d52019-04-15 16:31:54 -040022 const SkSL::String& sksl,
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -040023 const SkSL::Program::Settings& settings,
Brian Osman5e7fbfd2019-05-03 13:13:35 -040024 SkSL::String* glsl,
25 GrContextOptions::ShaderErrorHandler* errorHandler) {
Brian Osman79719262020-11-23 14:54:33 -050026 SkSL::Compiler* compiler = gpu->shaderCompiler();
Ethan Nicholas068acd52017-05-26 14:53:23 -040027 std::unique_ptr<SkSL::Program> program;
Brian Osman1e2d4a12019-06-06 15:25:44 -040028#ifdef SK_DEBUG
29 SkSL::String src = GrShaderUtils::PrettyPrint(sksl);
30#else
31 const SkSL::String& src = sksl;
32#endif
33 program = compiler->convertProgram(programKind, src, settings);
Ethan Nicholas068acd52017-05-26 14:53:23 -040034 if (!program || !compiler->toGLSL(*program, glsl)) {
Brian Osman1e2d4a12019-06-06 15:25:44 -040035 errorHandler->compileError(src.c_str(), compiler->errorText().c_str());
Brian Salomone334c592017-05-15 11:00:58 -040036 return nullptr;
37 }
Brian Osmanac9be9d2019-05-01 10:29:34 -040038
39 if (gPrintSKSL || gPrintGLSL) {
Robert Phillips797831c2020-11-20 22:35:55 +000040 GrShaderUtils::PrintShaderBanner(programKind);
Brian Osmanac9be9d2019-05-01 10:29:34 -040041 if (gPrintSKSL) {
Chris Dalton77912982019-12-16 11:18:13 -070042 SkDebugf("SKSL:\n");
43 GrShaderUtils::PrintLineByLine(GrShaderUtils::PrettyPrint(sksl));
Brian Osmanac9be9d2019-05-01 10:29:34 -040044 }
45 if (gPrintGLSL) {
Chris Dalton77912982019-12-16 11:18:13 -070046 SkDebugf("GLSL:\n");
47 GrShaderUtils::PrintLineByLine(GrShaderUtils::PrettyPrint(*glsl));
Brian Osmanac9be9d2019-05-01 10:29:34 -040048 }
Brian Salomon06ab3832017-12-04 16:45:30 -050049 }
Brian Osmanac9be9d2019-05-01 10:29:34 -040050
Ethan Nicholas068acd52017-05-26 14:53:23 -040051 return program;
Brian Salomone334c592017-05-15 11:00:58 -040052}
ethannicholas5961bc92016-10-12 06:39:56 -070053
joshualitt30ba4362014-08-21 20:18:45 -070054GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx,
55 GrGLuint programId,
56 GrGLenum type,
Brian Osmanac9be9d2019-05-01 10:29:34 -040057 const SkSL::String& glsl,
Robert Phillipsae67c522021-03-03 11:03:38 -050058 GrThreadSafePipelineBuilder::Stats* stats,
Brian Osman5e7fbfd2019-05-03 13:13:35 -040059 GrContextOptions::ShaderErrorHandler* errorHandler) {
Brian Osmand010f652021-02-24 13:59:39 -050060 TRACE_EVENT0_ALWAYS("skia.gpu", "driver_compile_shader");
Jim Van Verth03b8ab22020-02-24 11:36:15 -050061 const GrGLInterface* gli = glCtx.glInterface();
joshualitt30ba4362014-08-21 20:18:45 -070062
Brian Salomone334c592017-05-15 11:00:58 -040063 // Specify GLSL source to the driver.
robertphillips754f4e92014-09-18 13:52:08 -070064 GrGLuint shaderId;
65 GR_GL_CALL_RET(gli, shaderId, CreateShader(type));
66 if (0 == shaderId) {
67 return 0;
68 }
Brian Osmanac9be9d2019-05-01 10:29:34 -040069 const GrGLchar* source = glsl.c_str();
70 GrGLint sourceLength = glsl.size();
71 GR_GL_CALL(gli, ShaderSource(shaderId, 1, &source, &sourceLength));
joshualitt43466a12015-02-13 17:18:27 -080072
mtkleinb9eb4ac2015-02-02 18:26:03 -080073 stats->incShaderCompilations();
robertphillips754f4e92014-09-18 13:52:08 -070074 GR_GL_CALL(gli, CompileShader(shaderId));
joshualitt30ba4362014-08-21 20:18:45 -070075
Brian Salomond8575452020-02-25 12:13:29 -050076 bool checkCompiled = !glCtx.caps()->skipErrorChecks();
77
robertphillips754f4e92014-09-18 13:52:08 -070078 if (checkCompiled) {
Leon Scrogginsb66214e2021-02-11 17:14:18 -050079 ATRACE_ANDROID_FRAMEWORK("checkCompiled");
robertphillips754f4e92014-09-18 13:52:08 -070080 GrGLint compiled = GR_GL_INIT_ZERO;
81 GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled));
joshualitt30ba4362014-08-21 20:18:45 -070082
robertphillips754f4e92014-09-18 13:52:08 -070083 if (!compiled) {
84 GrGLint infoLen = GR_GL_INIT_ZERO;
85 GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen));
86 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
87 if (infoLen > 0) {
88 // retrieve length even though we don't need it to workaround bug in Chromium cmd
89 // buffer param validation.
90 GrGLsizei length = GR_GL_INIT_ZERO;
joshualitt43466a12015-02-13 17:18:27 -080091 GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, &length, (char*)log.get()));
robertphillips754f4e92014-09-18 13:52:08 -070092 }
Brian Osman5e7fbfd2019-05-03 13:13:35 -040093 errorHandler->compileError(glsl.c_str(), infoLen > 0 ? (const char*)log.get() : "");
robertphillips754f4e92014-09-18 13:52:08 -070094 GR_GL_CALL(gli, DeleteShader(shaderId));
95 return 0;
96 }
97 }
joshualitt30ba4362014-08-21 20:18:45 -070098
robertphillips754f4e92014-09-18 13:52:08 -070099 // Attach the shader, but defer deletion until after we have linked the program.
100 // This works around a bug in the Android emulator's GLES2 wrapper which
101 // will immediately delete the shader object and free its memory even though it's
102 // attached to a program, which then causes glLinkProgram to fail.
103 GR_GL_CALL(gli, AttachShader(programId, shaderId));
robertphillips754f4e92014-09-18 13:52:08 -0700104 return shaderId;
joshualitt30ba4362014-08-21 20:18:45 -0700105}