Hook up ShaderErrorHandler in the Metal backend.
Also cleans up dumping of shader code to use GrShaderUtils.
Change-Id: I4d2a13e1a54284d7da0242b74cebb3900921fc35
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/337077
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/GrShaderUtils.cpp b/src/gpu/GrShaderUtils.cpp
index 56661a8..ea77eb1 100644
--- a/src/gpu/GrShaderUtils.cpp
+++ b/src/gpu/GrShaderUtils.cpp
@@ -214,4 +214,15 @@
return &gHandler;
}
+void PrintShaderBanner(SkSL::Program::Kind programKind) {
+ const char* typeName = "Unknown";
+ switch (programKind) {
+ case SkSL::Program::kVertex_Kind: typeName = "Vertex"; break;
+ case SkSL::Program::kGeometry_Kind: typeName = "Geometry"; break;
+ case SkSL::Program::kFragment_Kind: typeName = "Fragment"; break;
+ default: break;
+ }
+ SkDebugf("---- %s shader ----------------------------------------------------\n", typeName);
+}
+
} // namespace GrShaderUtils
diff --git a/src/gpu/GrShaderUtils.h b/src/gpu/GrShaderUtils.h
index b9995ce..c41906f 100644
--- a/src/gpu/GrShaderUtils.h
+++ b/src/gpu/GrShaderUtils.h
@@ -11,6 +11,7 @@
#include "include/core/SkTypes.h"
#include "include/gpu/GrContextOptions.h"
#include "src/sksl/SkSLString.h"
+#include "src/sksl/ir/SkSLProgram.h"
namespace GrShaderUtils {
@@ -28,6 +29,8 @@
GrContextOptions::ShaderErrorHandler* DefaultShaderErrorHandler();
+void PrintShaderBanner(SkSL::Program::Kind programKind);
+
} // namespace GrShaderUtils
#endif
diff --git a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
index c3d3406..ff59dc0 100644
--- a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
@@ -17,17 +17,6 @@
static const bool gPrintSKSL = false;
static const bool gPrintGLSL = false;
-void print_shader_banner(SkSL::Program::Kind programKind) {
- const char* typeName = "Unknown";
- switch (programKind) {
- case SkSL::Program::kVertex_Kind: typeName = "Vertex"; break;
- case SkSL::Program::kGeometry_Kind: typeName = "Geometry"; break;
- case SkSL::Program::kFragment_Kind: typeName = "Fragment"; break;
- default: break;
- }
- SkDebugf("---- %s shader ----------------------------------------------------\n", typeName);
-}
-
std::unique_ptr<SkSL::Program> GrSkSLtoGLSL(const GrGLContext& context,
SkSL::Program::Kind programKind,
const SkSL::String& sksl,
@@ -48,7 +37,7 @@
}
if (gPrintSKSL || gPrintGLSL) {
- print_shader_banner(programKind);
+ GrShaderUtils::PrintShaderBanner(programKind);
if (gPrintSKSL) {
SkDebugf("SKSL:\n");
GrShaderUtils::PrintLineByLine(GrShaderUtils::PrettyPrint(sksl));
diff --git a/src/gpu/mtl/GrMtlPipelineStateBuilder.h b/src/gpu/mtl/GrMtlPipelineStateBuilder.h
index 166d087..a3c8a3b 100644
--- a/src/gpu/mtl/GrMtlPipelineStateBuilder.h
+++ b/src/gpu/mtl/GrMtlPipelineStateBuilder.h
@@ -53,12 +53,13 @@
SkSL::Program::Kind kind,
const SkSL::Program::Settings& settings,
SkSL::String* msl,
- SkSL::Program::Inputs* inputs);
+ SkSL::Program::Inputs* inputs,
+ GrContextOptions::ShaderErrorHandler* errorHandler);
id<MTLLibrary> compileMtlShaderLibrary(const SkSL::String& shader,
- SkSL::Program::Inputs inputs);
+ SkSL::Program::Inputs inputs,
+ GrContextOptions::ShaderErrorHandler* errorHandler);
void storeShadersInCache(const SkSL::String shaders[], const SkSL::Program::Inputs inputs[],
bool isSkSL);
- bool loadShadersFromCache(SkReadBuffer* cached, __strong id<MTLLibrary> outLibraries[]);
GrGLSLUniformHandler* uniformHandler() override { return &fUniformHandler; }
const GrGLSLUniformHandler* uniformHandler() const override { return &fUniformHandler; }
diff --git a/src/gpu/mtl/GrMtlPipelineStateBuilder.mm b/src/gpu/mtl/GrMtlPipelineStateBuilder.mm
index fb61346..140b1a2 100644
--- a/src/gpu/mtl/GrMtlPipelineStateBuilder.mm
+++ b/src/gpu/mtl/GrMtlPipelineStateBuilder.mm
@@ -66,27 +66,6 @@
static constexpr SkFourByteTag kSKSL_Tag = SkSetFourByteTag('S', 'K', 'S', 'L');
-bool GrMtlPipelineStateBuilder::loadShadersFromCache(SkReadBuffer* cached,
- __strong id<MTLLibrary> outLibraries[]) {
- SkSL::String shaders[kGrShaderTypeCount];
- SkSL::Program::Inputs inputs[kGrShaderTypeCount];
-
- if (!GrPersistentCacheUtils::UnpackCachedShaders(cached, shaders, inputs, kGrShaderTypeCount)) {
- return false;
- }
-
- outLibraries[kVertex_GrShaderType] = this->compileMtlShaderLibrary(
- shaders[kVertex_GrShaderType],
- inputs[kVertex_GrShaderType]);
- outLibraries[kFragment_GrShaderType] = this->compileMtlShaderLibrary(
- shaders[kFragment_GrShaderType],
- inputs[kFragment_GrShaderType]);
-
- return outLibraries[kVertex_GrShaderType] &&
- outLibraries[kFragment_GrShaderType] &&
- shaders[kGeometry_GrShaderType].empty(); // Geometry shaders are not supported
-}
-
void GrMtlPipelineStateBuilder::storeShadersInCache(const SkSL::String shaders[],
const SkSL::Program::Inputs inputs[],
bool isSkSL) {
@@ -106,18 +85,21 @@
SkSL::Program::Kind kind,
const SkSL::Program::Settings& settings,
SkSL::String* msl,
- SkSL::Program::Inputs* inputs) {
+ SkSL::Program::Inputs* inputs,
+ GrContextOptions::ShaderErrorHandler* errorHandler) {
id<MTLLibrary> shaderLibrary = GrGenerateMtlShaderLibrary(fGpu, shader,
- kind, settings, msl, inputs);
+ kind, settings, msl, inputs,
+ errorHandler);
if (shaderLibrary != nil && inputs->fRTHeight) {
this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
}
return shaderLibrary;
}
-id<MTLLibrary> GrMtlPipelineStateBuilder::compileMtlShaderLibrary(const SkSL::String& shader,
- SkSL::Program::Inputs inputs) {
- id<MTLLibrary> shaderLibrary = GrCompileMtlShaderLibrary(fGpu, shader);
+id<MTLLibrary> GrMtlPipelineStateBuilder::compileMtlShaderLibrary(
+ const SkSL::String& shader, SkSL::Program::Inputs inputs,
+ GrContextOptions::ShaderErrorHandler* errorHandler) {
+ id<MTLLibrary> shaderLibrary = GrCompileMtlShaderLibrary(fGpu, shader, errorHandler);
if (shaderLibrary != nil && inputs.fRTHeight) {
this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
}
@@ -413,12 +395,23 @@
}
}
- if (kMSL_Tag == shaderType && this->loadShadersFromCache(&reader, shaderLibraries)) {
- // We successfully loaded and compiled MSL
+ auto errorHandler = fGpu->getContext()->priv().getShaderErrorHandler();
+ SkSL::String shaders[kGrShaderTypeCount];
+ SkSL::Program::Inputs inputs[kGrShaderTypeCount];
+ if (kMSL_Tag == shaderType &&
+ GrPersistentCacheUtils::UnpackCachedShaders(&reader, shaders, inputs, kGrShaderTypeCount)) {
+ shaderLibraries[kVertex_GrShaderType] = this->compileMtlShaderLibrary(
+ shaders[kVertex_GrShaderType],
+ inputs[kVertex_GrShaderType],
+ errorHandler);
+ shaderLibraries[kFragment_GrShaderType] = this->compileMtlShaderLibrary(
+ shaders[kFragment_GrShaderType],
+ inputs[kFragment_GrShaderType],
+ errorHandler);
+ if (!shaderLibraries[kVertex_GrShaderType] || !shaderLibraries[kFragment_GrShaderType]) {
+ return nullptr;
+ }
} else {
- SkSL::String shaders[kGrShaderTypeCount];
- SkSL::Program::Inputs inputs[kGrShaderTypeCount];
-
SkSL::String* sksl[kGrShaderTypeCount] = {
&fVS.fCompilerString,
nullptr, // geometry shaders not supported
@@ -439,17 +432,15 @@
SkSL::Program::kVertex_Kind,
settings,
&shaders[kVertex_GrShaderType],
- &inputs[kVertex_GrShaderType]);
+ &inputs[kVertex_GrShaderType],
+ errorHandler);
shaderLibraries[kFragment_GrShaderType] = this->generateMtlShaderLibrary(
*sksl[kFragment_GrShaderType],
SkSL::Program::kFragment_Kind,
settings,
&shaders[kFragment_GrShaderType],
- &inputs[kFragment_GrShaderType]);
-
- // Geometry shaders are not supported
- SkASSERT(!this->primitiveProcessor().willUseGeoShader());
-
+ &inputs[kFragment_GrShaderType],
+ errorHandler);
if (!shaderLibraries[kVertex_GrShaderType] || !shaderLibraries[kFragment_GrShaderType]) {
return nullptr;
}
@@ -469,6 +460,9 @@
}
}
+ // Geometry shaders are not supported
+ SkASSERT(!this->primitiveProcessor().willUseGeoShader());
+
id<MTLFunction> vertexFunction =
[shaderLibraries[kVertex_GrShaderType] newFunctionWithName: @"vertexMain"];
id<MTLFunction> fragmentFunction =
diff --git a/src/gpu/mtl/GrMtlUtil.h b/src/gpu/mtl/GrMtlUtil.h
index cb11f52..97f3580 100644
--- a/src/gpu/mtl/GrMtlUtil.h
+++ b/src/gpu/mtl/GrMtlUtil.h
@@ -69,17 +69,19 @@
* Returns a compiled MTLLibrary created from MSL code generated by SkSLC
*/
id<MTLLibrary> GrGenerateMtlShaderLibrary(const GrMtlGpu* gpu,
- const SkSL::String& shaderString,
+ const SkSL::String& sksl,
SkSL::Program::Kind kind,
const SkSL::Program::Settings& settings,
- SkSL::String* mslShader,
- SkSL::Program::Inputs* outInputs);
+ SkSL::String* msl,
+ SkSL::Program::Inputs* outInputs,
+ GrContextOptions::ShaderErrorHandler* errorHandler);
/**
* Returns a compiled MTLLibrary created from MSL code
*/
id<MTLLibrary> GrCompileMtlShaderLibrary(const GrMtlGpu* gpu,
- const SkSL::String& shaderString);
+ const SkSL::String& msl,
+ GrContextOptions::ShaderErrorHandler* errorHandler);
/**
* Replacement for newLibraryWithSource:options:error that has a timeout.
diff --git a/src/gpu/mtl/GrMtlUtil.mm b/src/gpu/mtl/GrMtlUtil.mm
index c24cc2c..ac74882 100644
--- a/src/gpu/mtl/GrMtlUtil.mm
+++ b/src/gpu/mtl/GrMtlUtil.mm
@@ -10,6 +10,7 @@
#include "include/gpu/GrBackendSurface.h"
#include "include/private/GrTypesPriv.h"
#include "include/private/SkMutex.h"
+#include "src/gpu/GrShaderUtils.h"
#include "src/gpu/GrSurface.h"
#include "src/gpu/mtl/GrMtlGpu.h"
#include "src/gpu/mtl/GrMtlRenderTarget.h"
@@ -22,8 +23,6 @@
#error This file must be compiled with Arc. Use -fobjc-arc flag
#endif
-#define PRINT_MSL 0 // print out the MSL code generated
-
NSError* GrCreateMtlError(NSString* description, GrMtlErrorCode errorCode) {
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:description
forKey:NSLocalizedDescriptionKey];
@@ -48,55 +47,55 @@
return texDesc;
}
-#if PRINT_MSL
-void print_msl(const char* source) {
- SkTArray<SkString> lines;
- SkStrSplit(source, "\n", kStrict_SkStrSplitMode, &lines);
- for (int i = 0; i < lines.count(); i++) {
- SkString& line = lines[i];
- line.prependf("%4i\t", i + 1);
- SkDebugf("%s\n", line.c_str());
- }
-}
-#endif
+// Print the source code for all shaders generated.
+static const bool gPrintSKSL = false;
+static const bool gPrintMSL = false;
id<MTLLibrary> GrGenerateMtlShaderLibrary(const GrMtlGpu* gpu,
- const SkSL::String& shaderString,
- SkSL::Program::Kind kind,
+ const SkSL::String& sksl,
+ SkSL::Program::Kind programKind,
const SkSL::Program::Settings& settings,
- SkSL::String* mslShader,
- SkSL::Program::Inputs* outInputs) {
+ SkSL::String* msl,
+ SkSL::Program::Inputs* outInputs,
+ GrContextOptions::ShaderErrorHandler* errorHandler) {
+#ifdef SK_DEBUG
+ SkSL::String src = GrShaderUtils::PrettyPrint(sksl);
+#else
+ const SkSL::String& src = sksl;
+#endif
+ SkSL::Compiler* compiler = gpu->shaderCompiler();
std::unique_ptr<SkSL::Program> program =
- gpu->shaderCompiler()->convertProgram(kind,
- shaderString,
+ gpu->shaderCompiler()->convertProgram(programKind,
+ src,
settings);
-
- if (!program) {
- SkDebugf("SkSL error:\n%s\n", gpu->shaderCompiler()->errorText().c_str());
- SkASSERT(false);
+ if (!program || !compiler->toMetal(*program, msl)) {
+ errorHandler->compileError(src.c_str(), compiler->errorText().c_str());
return nil;
}
+ if (gPrintSKSL || gPrintMSL) {
+ GrShaderUtils::PrintShaderBanner(programKind);
+ if (gPrintSKSL) {
+ SkDebugf("SKSL:\n");
+ GrShaderUtils::PrintLineByLine(GrShaderUtils::PrettyPrint(sksl));
+ }
+ if (gPrintMSL) {
+ SkDebugf("MSL:\n");
+ GrShaderUtils::PrintLineByLine(GrShaderUtils::PrettyPrint(*msl));
+ }
+ }
+
*outInputs = program->fInputs;
- if (!gpu->shaderCompiler()->toMetal(*program, mslShader)) {
- SkDebugf("%s\n", gpu->shaderCompiler()->errorText().c_str());
- SkASSERT(false);
- return nil;
- }
-
- return GrCompileMtlShaderLibrary(gpu, *mslShader);
+ return GrCompileMtlShaderLibrary(gpu, *msl, errorHandler);
}
id<MTLLibrary> GrCompileMtlShaderLibrary(const GrMtlGpu* gpu,
- const SkSL::String& shaderString) {
- auto nsSource = [[NSString alloc] initWithBytesNoCopy:const_cast<char*>(shaderString.c_str())
- length:shaderString.size()
+ const SkSL::String& msl,
+ GrContextOptions::ShaderErrorHandler* errorHandler) {
+ auto nsSource = [[NSString alloc] initWithBytesNoCopy:const_cast<char*>(msl.c_str())
+ length:msl.size()
encoding:NSUTF8StringEncoding
freeWhenDone:NO];
-#if PRINT_MSL
- print_msl(nsSource.UTF8String);
-#endif
-
NSError* error = nil;
#if defined(SK_BUILD_FOR_MAC)
id<MTLLibrary> compiledLibrary = GrMtlNewLibraryWithSource(gpu->device(), nsSource,
@@ -107,9 +106,7 @@
error:&error];
#endif
if (!compiledLibrary) {
- SkDebugf("Error compiling MSL shader: %s\n%s\n",
- shaderString.c_str(),
- error.debugDescription.UTF8String);
+ errorHandler->compileError(msl.c_str(), error.debugDescription.UTF8String);
return nil;
}