Move ProgramKind and ProgramSettings types out of SkSL::Program.
This change will allow these types to be forward-declared; C++ doesn't allow forward declaration of types declared inside a struct. Moving these types out of Programs resulted in a large diff. The Settings::Value helper class has been moved inside of the IRGenerator. In practice, it was actually just an implementation detail of how IRGenerator looks up caps-values by name. It seems very unlikely that this will be necessary elsewhere going forward. Change-Id: I6119417fae608f1c492a27de746d2b550ef8ca20 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/370836 Reviewed-by: Ethan Nicholas <ethannicholas@google.com> Commit-Queue: Ethan Nicholas <ethannicholas@google.com> Commit-Queue: John Stiles <johnstiles@google.com> Auto-Submit: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
ff0cd8c506
commit
dbd4e6f0c0
@ -79,7 +79,7 @@ protected:
|
||||
void onDraw(int loops, SkCanvas* canvas) override {
|
||||
for (int i = 0; i < loops; i++) {
|
||||
std::unique_ptr<SkSL::Program> program = fCompiler.convertProgram(
|
||||
SkSL::Program::kFragment_Kind,
|
||||
SkSL::ProgramKind::kFragment,
|
||||
fSrc,
|
||||
fSettings);
|
||||
if (fCompiler.errorCount()) {
|
||||
@ -124,8 +124,7 @@ protected:
|
||||
}
|
||||
|
||||
void onDelayedSetup() override {
|
||||
SkSL::ParsedModule module = fCompiler.moduleForProgramKind(
|
||||
SkSL::Program::Kind::kFragment_Kind);
|
||||
SkSL::ParsedModule module = fCompiler.moduleForProgramKind(SkSL::ProgramKind::kFragment);
|
||||
fCompiler.irGenerator().setSymbolTable(module.fSymbols);
|
||||
}
|
||||
|
||||
@ -584,8 +583,8 @@ void RunSkSLMemoryBenchmarks(NanoJSONResultsWriter* log) {
|
||||
int before = heap_bytes_used();
|
||||
GrShaderCaps caps(GrContextOptions{});
|
||||
SkSL::Compiler compiler(&caps);
|
||||
compiler.moduleForProgramKind(SkSL::Program::kVertex_Kind);
|
||||
compiler.moduleForProgramKind(SkSL::Program::kFragment_Kind);
|
||||
compiler.moduleForProgramKind(SkSL::ProgramKind::kVertex);
|
||||
compiler.moduleForProgramKind(SkSL::ProgramKind::kFragment);
|
||||
int after = heap_bytes_used();
|
||||
bench("sksl_compiler_gpu", after - before);
|
||||
}
|
||||
@ -595,7 +594,7 @@ void RunSkSLMemoryBenchmarks(NanoJSONResultsWriter* log) {
|
||||
int before = heap_bytes_used();
|
||||
GrShaderCaps caps(GrContextOptions{});
|
||||
SkSL::Compiler compiler(&caps);
|
||||
compiler.moduleForProgramKind(SkSL::Program::kRuntimeEffect_Kind);
|
||||
compiler.moduleForProgramKind(SkSL::ProgramKind::kRuntimeEffect);
|
||||
int after = heap_bytes_used();
|
||||
bench("sksl_compiler_runtimeeffect", after - before);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ bool FuzzSKSL2GLSL(sk_sp<SkData> bytes) {
|
||||
SkSL::String output;
|
||||
SkSL::Program::Settings settings;
|
||||
std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
|
||||
SkSL::Program::kFragment_Kind,
|
||||
SkSL::ProgramKind::kFragment,
|
||||
SkSL::String((const char*) bytes->data(),
|
||||
bytes->size()),
|
||||
settings);
|
||||
|
@ -16,7 +16,7 @@ bool FuzzSKSL2Metal(sk_sp<SkData> bytes) {
|
||||
SkSL::String output;
|
||||
SkSL::Program::Settings settings;
|
||||
std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
|
||||
SkSL::Program::kFragment_Kind,
|
||||
SkSL::ProgramKind::kFragment,
|
||||
SkSL::String((const char*) bytes->data(),
|
||||
bytes->size()),
|
||||
settings);
|
||||
|
@ -18,7 +18,7 @@ bool FuzzSKSL2Pipeline(sk_sp<SkData> bytes) {
|
||||
SkSL::Compiler compiler(caps.get());
|
||||
SkSL::Program::Settings settings;
|
||||
std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
|
||||
SkSL::Program::kRuntimeEffect_Kind,
|
||||
SkSL::ProgramKind::kRuntimeEffect,
|
||||
SkSL::String((const char*) bytes->data(),
|
||||
bytes->size()),
|
||||
settings);
|
||||
|
@ -16,7 +16,7 @@ bool FuzzSKSL2SPIRV(sk_sp<SkData> bytes) {
|
||||
SkSL::String output;
|
||||
SkSL::Program::Settings settings;
|
||||
std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
|
||||
SkSL::Program::kFragment_Kind,
|
||||
SkSL::ProgramKind::kFragment,
|
||||
SkSL::String((const char*) bytes->data(),
|
||||
bytes->size()),
|
||||
settings);
|
||||
|
@ -161,7 +161,7 @@ void SkParticleEffectParams::prepare(const skresources::ResourceProvider* resour
|
||||
}
|
||||
|
||||
auto program =
|
||||
compiler.convertProgram(SkSL::Program::kGeneric_Kind, code, settings, &externalFns);
|
||||
compiler.convertProgram(SkSL::ProgramKind::kGeneric, code, settings, &externalFns);
|
||||
if (!program) {
|
||||
SkDebugf("%s\n", compiler.errorText().c_str());
|
||||
return nullptr;
|
||||
|
@ -137,7 +137,7 @@ SkRuntimeEffect::Result SkRuntimeEffect::Make(SkString sksl, const Options& opti
|
||||
SkSL::Program::Settings settings;
|
||||
settings.fInlineThreshold = options.inlineThreshold;
|
||||
settings.fAllowNarrowingConversions = true;
|
||||
auto program = compiler->convertProgram(SkSL::Program::kRuntimeEffect_Kind,
|
||||
auto program = compiler->convertProgram(SkSL::ProgramKind::kRuntimeEffect,
|
||||
SkSL::String(sksl.c_str(), sksl.size()),
|
||||
settings);
|
||||
// TODO: Many errors aren't caught until we process the generated Program here. Catching those
|
||||
|
@ -214,12 +214,12 @@ GrContextOptions::ShaderErrorHandler* DefaultShaderErrorHandler() {
|
||||
return &gHandler;
|
||||
}
|
||||
|
||||
void PrintShaderBanner(SkSL::Program::Kind programKind) {
|
||||
void PrintShaderBanner(SkSL::ProgramKind 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;
|
||||
case SkSL::ProgramKind::kVertex: typeName = "Vertex"; break;
|
||||
case SkSL::ProgramKind::kGeometry: typeName = "Geometry"; break;
|
||||
case SkSL::ProgramKind::kFragment: typeName = "Fragment"; break;
|
||||
default: break;
|
||||
}
|
||||
SkDebugf("---- %s shader ----------------------------------------------------\n", typeName);
|
||||
|
@ -29,7 +29,7 @@ inline void PrintLineByLine(const SkSL::String& text) {
|
||||
|
||||
GrContextOptions::ShaderErrorHandler* DefaultShaderErrorHandler();
|
||||
|
||||
void PrintShaderBanner(SkSL::Program::Kind programKind);
|
||||
void PrintShaderBanner(SkSL::ProgramKind programKind);
|
||||
|
||||
} // namespace GrShaderUtils
|
||||
|
||||
|
@ -72,16 +72,16 @@ void GrD3DPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outp
|
||||
|
||||
static gr_cp<ID3DBlob> GrCompileHLSLShader(GrD3DGpu* gpu,
|
||||
const SkSL::String& hlsl,
|
||||
SkSL::Program::Kind kind) {
|
||||
SkSL::ProgramKind kind) {
|
||||
const char* compileTarget = nullptr;
|
||||
switch (kind) {
|
||||
case SkSL::Program::kVertex_Kind:
|
||||
case SkSL::ProgramKind::kVertex:
|
||||
compileTarget = "vs_5_1";
|
||||
break;
|
||||
case SkSL::Program::kGeometry_Kind:
|
||||
case SkSL::ProgramKind::kGeometry:
|
||||
compileTarget = "gs_5_1";
|
||||
break;
|
||||
case SkSL::Program::kFragment_Kind:
|
||||
case SkSL::ProgramKind::kFragment:
|
||||
compileTarget = "ps_5_1";
|
||||
break;
|
||||
default:
|
||||
@ -116,7 +116,7 @@ bool GrD3DPipelineStateBuilder::loadHLSLFromCache(SkReadBuffer* reader, gr_cp<ID
|
||||
return false;
|
||||
}
|
||||
|
||||
auto compile = [&](SkSL::Program::Kind kind, GrShaderType shaderType) {
|
||||
auto compile = [&](SkSL::ProgramKind kind, GrShaderType shaderType) {
|
||||
if (inputs[shaderType].fRTHeight) {
|
||||
this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
|
||||
}
|
||||
@ -124,14 +124,14 @@ bool GrD3DPipelineStateBuilder::loadHLSLFromCache(SkReadBuffer* reader, gr_cp<ID
|
||||
return shaders[shaderType].get();
|
||||
};
|
||||
|
||||
return compile(SkSL::Program::kVertex_Kind, kVertex_GrShaderType) &&
|
||||
compile(SkSL::Program::kFragment_Kind, kFragment_GrShaderType) &&
|
||||
return compile(SkSL::ProgramKind::kVertex, kVertex_GrShaderType) &&
|
||||
compile(SkSL::ProgramKind::kFragment, kFragment_GrShaderType) &&
|
||||
(hlsl[kGeometry_GrShaderType].empty() ||
|
||||
compile(SkSL::Program::kGeometry_Kind, kGeometry_GrShaderType));
|
||||
compile(SkSL::ProgramKind::kGeometry, kGeometry_GrShaderType));
|
||||
}
|
||||
|
||||
gr_cp<ID3DBlob> GrD3DPipelineStateBuilder::compileD3DProgram(
|
||||
SkSL::Program::Kind kind,
|
||||
SkSL::ProgramKind kind,
|
||||
const SkSL::String& sksl,
|
||||
const SkSL::Program::Settings& settings,
|
||||
SkSL::Program::Inputs* outInputs,
|
||||
@ -601,19 +601,19 @@ sk_sp<GrD3DPipelineState> GrD3DPipelineStateBuilder::finalize() {
|
||||
}
|
||||
}
|
||||
|
||||
auto compile = [&](SkSL::Program::Kind kind, GrShaderType shaderType) {
|
||||
auto compile = [&](SkSL::ProgramKind kind, GrShaderType shaderType) {
|
||||
shaders[shaderType] = this->compileD3DProgram(kind, *sksl[shaderType], settings,
|
||||
&inputs[shaderType], &hlsl[shaderType]);
|
||||
return shaders[shaderType].get();
|
||||
};
|
||||
|
||||
if (!compile(SkSL::Program::kVertex_Kind, kVertex_GrShaderType) ||
|
||||
!compile(SkSL::Program::kFragment_Kind, kFragment_GrShaderType)) {
|
||||
if (!compile(SkSL::ProgramKind::kVertex, kVertex_GrShaderType) ||
|
||||
!compile(SkSL::ProgramKind::kFragment, kFragment_GrShaderType)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (primProc.willUseGeoShader()) {
|
||||
if (!compile(SkSL::Program::kGeometry_Kind, kGeometry_GrShaderType)) {
|
||||
if (!compile(SkSL::ProgramKind::kGeometry, kGeometry_GrShaderType)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ private:
|
||||
|
||||
bool loadHLSLFromCache(SkReadBuffer* reader, gr_cp<ID3DBlob> shaders[]);
|
||||
|
||||
gr_cp<ID3DBlob> compileD3DProgram(SkSL::Program::Kind kind,
|
||||
gr_cp<ID3DBlob> compileD3DProgram(SkSL::ProgramKind kind,
|
||||
const SkSL::String& sksl,
|
||||
const SkSL::Program::Settings& settings,
|
||||
SkSL::Program::Inputs* outInputs,
|
||||
|
@ -704,7 +704,7 @@ bool GrDawnGpu::onRegenerateMipMapLevels(GrTexture* tex) {
|
||||
" texCoord = texCoords[sk_VertexID];\n"
|
||||
"}\n";
|
||||
SkSL::String vsSPIRV =
|
||||
this->SkSLToSPIRV(vs, SkSL::Program::kVertex_Kind, false, 0, nullptr);
|
||||
this->SkSLToSPIRV(vs, SkSL::ProgramKind::kVertex, false, 0, nullptr);
|
||||
|
||||
const char* fs =
|
||||
"layout(set = 0, binding = 0) uniform sampler samp;\n"
|
||||
@ -714,7 +714,7 @@ bool GrDawnGpu::onRegenerateMipMapLevels(GrTexture* tex) {
|
||||
" sk_FragColor = sample(makeSampler2D(tex, samp), texCoord);\n"
|
||||
"}\n";
|
||||
SkSL::String fsSPIRV =
|
||||
this->SkSLToSPIRV(fs, SkSL::Program::kFragment_Kind, false, 0, nullptr);
|
||||
this->SkSLToSPIRV(fs, SkSL::ProgramKind::kFragment, false, 0, nullptr);
|
||||
|
||||
wgpu::ProgrammableStageDescriptor vsDesc;
|
||||
vsDesc.module = this->createShaderModule(vsSPIRV);
|
||||
@ -925,7 +925,7 @@ void GrDawnGpu::moveStagingBuffersToBusyAndMapAsync() {
|
||||
fSubmittedStagingBuffers.clear();
|
||||
}
|
||||
|
||||
SkSL::String GrDawnGpu::SkSLToSPIRV(const char* shaderString, SkSL::Program::Kind kind, bool flipY,
|
||||
SkSL::String GrDawnGpu::SkSLToSPIRV(const char* shaderString, SkSL::ProgramKind kind, bool flipY,
|
||||
uint32_t rtHeightOffset, SkSL::Program::Inputs* inputs) {
|
||||
SkSL::Program::Settings settings;
|
||||
settings.fFlipY = flipY;
|
||||
|
@ -99,7 +99,7 @@ public:
|
||||
void appendCommandBuffer(wgpu::CommandBuffer commandBuffer);
|
||||
|
||||
void waitOnAllBusyStagingBuffers();
|
||||
SkSL::String SkSLToSPIRV(const char* shaderString, SkSL::Program::Kind, bool flipY,
|
||||
SkSL::String SkSLToSPIRV(const char* shaderString, SkSL::ProgramKind, bool flipY,
|
||||
uint32_t rtHeightOffset, SkSL::Program::Inputs*);
|
||||
wgpu::ShaderModule createShaderModule(const SkSL::String& spirvSource);
|
||||
|
||||
|
@ -277,9 +277,9 @@ sk_sp<GrDawnProgram> GrDawnProgramBuilder::Build(GrDawnGpu* gpu,
|
||||
|
||||
SkSL::Program::Inputs vertInputs, fragInputs;
|
||||
bool flipY = programInfo.origin() != kTopLeft_GrSurfaceOrigin;
|
||||
auto vsModule = builder.createShaderModule(builder.fVS, SkSL::Program::kVertex_Kind, flipY,
|
||||
auto vsModule = builder.createShaderModule(builder.fVS, SkSL::ProgramKind::kVertex, flipY,
|
||||
&vertInputs);
|
||||
auto fsModule = builder.createShaderModule(builder.fFS, SkSL::Program::kFragment_Kind, flipY,
|
||||
auto fsModule = builder.createShaderModule(builder.fFS, SkSL::ProgramKind::kFragment, flipY,
|
||||
&fragInputs);
|
||||
GrSPIRVUniformHandler::UniformInfoArray& uniforms = builder.fUniformHandler.fUniforms;
|
||||
uint32_t uniformBufferSize = builder.fUniformHandler.fCurrentUBOOffset;
|
||||
@ -426,7 +426,7 @@ GrDawnProgramBuilder::GrDawnProgramBuilder(GrDawnGpu* gpu,
|
||||
}
|
||||
|
||||
wgpu::ShaderModule GrDawnProgramBuilder::createShaderModule(const GrGLSLShaderBuilder& builder,
|
||||
SkSL::Program::Kind kind,
|
||||
SkSL::ProgramKind kind,
|
||||
bool flipY,
|
||||
SkSL::Program::Inputs* inputs) {
|
||||
wgpu::Device device = fGpu->device();
|
||||
|
@ -93,7 +93,7 @@ private:
|
||||
GrRenderTarget*,
|
||||
const GrProgramInfo&,
|
||||
GrProgramDesc*);
|
||||
wgpu::ShaderModule createShaderModule(const GrGLSLShaderBuilder&, SkSL::Program::Kind,
|
||||
wgpu::ShaderModule createShaderModule(const GrGLSLShaderBuilder&, SkSL::ProgramKind,
|
||||
bool flipY, SkSL::Program::Inputs* inputs);
|
||||
GrDawnGpu* fGpu;
|
||||
GrSPIRVVaryingHandler fVaryingHandler;
|
||||
|
@ -3062,14 +3062,14 @@ bool GrGLGpu::createCopyProgram(GrTexture* srcTex) {
|
||||
SkSL::String sksl(vshaderTxt.c_str(), vshaderTxt.size());
|
||||
SkSL::Program::Settings settings;
|
||||
SkSL::String glsl;
|
||||
std::unique_ptr<SkSL::Program> program = GrSkSLtoGLSL(this, SkSL::Program::kVertex_Kind,
|
||||
std::unique_ptr<SkSL::Program> program = GrSkSLtoGLSL(this, SkSL::ProgramKind::kVertex,
|
||||
sksl, settings, &glsl, errorHandler);
|
||||
GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram,
|
||||
GR_GL_VERTEX_SHADER, glsl, &fStats, errorHandler);
|
||||
SkASSERT(program->fInputs.isEmpty());
|
||||
|
||||
sksl.assign(fshaderTxt.c_str(), fshaderTxt.size());
|
||||
program = GrSkSLtoGLSL(this, SkSL::Program::kFragment_Kind, sksl, settings, &glsl,
|
||||
program = GrSkSLtoGLSL(this, SkSL::ProgramKind::kFragment, sksl, settings, &glsl,
|
||||
errorHandler);
|
||||
GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram,
|
||||
GR_GL_FRAGMENT_SHADER, glsl, &fStats,
|
||||
@ -3215,14 +3215,14 @@ bool GrGLGpu::createMipmapProgram(int progIdx) {
|
||||
SkSL::String sksl(vshaderTxt.c_str(), vshaderTxt.size());
|
||||
SkSL::Program::Settings settings;
|
||||
SkSL::String glsl;
|
||||
std::unique_ptr<SkSL::Program> program = GrSkSLtoGLSL(this, SkSL::Program::kVertex_Kind,
|
||||
std::unique_ptr<SkSL::Program> program = GrSkSLtoGLSL(this, SkSL::ProgramKind::kVertex,
|
||||
sksl, settings, &glsl, errorHandler);
|
||||
GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fMipmapPrograms[progIdx].fProgram,
|
||||
GR_GL_VERTEX_SHADER, glsl, &fStats, errorHandler);
|
||||
SkASSERT(program->fInputs.isEmpty());
|
||||
|
||||
sksl.assign(fshaderTxt.c_str(), fshaderTxt.size());
|
||||
program = GrSkSLtoGLSL(this, SkSL::Program::kFragment_Kind, sksl, settings, &glsl,
|
||||
program = GrSkSLtoGLSL(this, SkSL::ProgramKind::kFragment, sksl, settings, &glsl,
|
||||
errorHandler);
|
||||
GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fMipmapPrograms[progIdx].fProgram,
|
||||
GR_GL_FRAGMENT_SHADER, glsl, &fStats,
|
||||
|
@ -334,7 +334,7 @@ sk_sp<GrGLProgram> GrGLProgramBuilder::finalize(const GrGLPrecompiledProgram* pr
|
||||
settings.fForceHighPrecision = true;
|
||||
}
|
||||
std::unique_ptr<SkSL::Program> fs = GrSkSLtoGLSL(this->gpu(),
|
||||
SkSL::Program::kFragment_Kind,
|
||||
SkSL::ProgramKind::kFragment,
|
||||
*sksl[kFragment_GrShaderType],
|
||||
settings,
|
||||
&glsl[kFragment_GrShaderType],
|
||||
@ -359,7 +359,7 @@ sk_sp<GrGLProgram> GrGLProgramBuilder::finalize(const GrGLPrecompiledProgram* pr
|
||||
if (glsl[kVertex_GrShaderType].empty()) {
|
||||
// Don't have cached GLSL, need to compile SkSL->GLSL
|
||||
std::unique_ptr<SkSL::Program> vs = GrSkSLtoGLSL(this->gpu(),
|
||||
SkSL::Program::kVertex_Kind,
|
||||
SkSL::ProgramKind::kVertex,
|
||||
*sksl[kVertex_GrShaderType],
|
||||
settings,
|
||||
&glsl[kVertex_GrShaderType],
|
||||
@ -423,7 +423,7 @@ sk_sp<GrGLProgram> GrGLProgramBuilder::finalize(const GrGLPrecompiledProgram* pr
|
||||
// Don't have cached GLSL, need to compile SkSL->GLSL
|
||||
std::unique_ptr<SkSL::Program> gs;
|
||||
gs = GrSkSLtoGLSL(this->gpu(),
|
||||
SkSL::Program::kGeometry_Kind,
|
||||
SkSL::ProgramKind::kGeometry,
|
||||
*sksl[kGeometry_GrShaderType],
|
||||
settings,
|
||||
&glsl[kGeometry_GrShaderType],
|
||||
@ -603,7 +603,7 @@ bool GrGLProgramBuilder::PrecompileProgram(GrGLPrecompiledProgram* precompiledPr
|
||||
|
||||
SkTDArray<GrGLuint> shadersToDelete;
|
||||
|
||||
auto compileShader = [&](SkSL::Program::Kind kind, const SkSL::String& sksl, GrGLenum type) {
|
||||
auto compileShader = [&](SkSL::ProgramKind kind, const SkSL::String& sksl, GrGLenum type) {
|
||||
SkSL::String glsl;
|
||||
auto program = GrSkSLtoGLSL(gpu, kind, sksl, settings, &glsl, errorHandler);
|
||||
if (!program) {
|
||||
@ -619,14 +619,14 @@ bool GrGLProgramBuilder::PrecompileProgram(GrGLPrecompiledProgram* precompiledPr
|
||||
}
|
||||
};
|
||||
|
||||
if (!compileShader(SkSL::Program::kFragment_Kind,
|
||||
if (!compileShader(SkSL::ProgramKind::kFragment,
|
||||
shaders[kFragment_GrShaderType],
|
||||
GR_GL_FRAGMENT_SHADER) ||
|
||||
!compileShader(SkSL::Program::kVertex_Kind,
|
||||
!compileShader(SkSL::ProgramKind::kVertex,
|
||||
shaders[kVertex_GrShaderType],
|
||||
GR_GL_VERTEX_SHADER) ||
|
||||
(!shaders[kGeometry_GrShaderType].empty() &&
|
||||
!compileShader(SkSL::Program::kGeometry_Kind,
|
||||
!compileShader(SkSL::ProgramKind::kGeometry,
|
||||
shaders[kGeometry_GrShaderType],
|
||||
GR_GL_GEOMETRY_SHADER))) {
|
||||
cleanup_program(gpu, programID, shadersToDelete);
|
||||
|
@ -18,7 +18,7 @@ static const bool gPrintSKSL = false;
|
||||
static const bool gPrintGLSL = false;
|
||||
|
||||
std::unique_ptr<SkSL::Program> GrSkSLtoGLSL(const GrGLGpu* gpu,
|
||||
SkSL::Program::Kind programKind,
|
||||
SkSL::ProgramKind programKind,
|
||||
const SkSL::String& sksl,
|
||||
const SkSL::Program::Settings& settings,
|
||||
SkSL::String* glsl,
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "src/sksl/SkSLGLSLCodeGenerator.h"
|
||||
|
||||
std::unique_ptr<SkSL::Program> GrSkSLtoGLSL(const GrGLGpu* gpu,
|
||||
SkSL::Program::Kind programKind,
|
||||
SkSL::ProgramKind programKind,
|
||||
const SkSL::String& sksl,
|
||||
const SkSL::Program::Settings& settings,
|
||||
SkSL::String* glsl,
|
||||
|
@ -52,7 +52,7 @@ private:
|
||||
void finalizeFragmentSecondaryColor(GrShaderVar& outputColor) override;
|
||||
|
||||
id<MTLLibrary> generateMtlShaderLibrary(const SkSL::String& sksl,
|
||||
SkSL::Program::Kind kind,
|
||||
SkSL::ProgramKind kind,
|
||||
const SkSL::Program::Settings& settings,
|
||||
SkSL::String* msl,
|
||||
SkSL::Program::Inputs* inputs,
|
||||
|
@ -86,7 +86,7 @@ void GrMtlPipelineStateBuilder::storeShadersInCache(const SkSL::String shaders[]
|
||||
|
||||
id<MTLLibrary> GrMtlPipelineStateBuilder::generateMtlShaderLibrary(
|
||||
const SkSL::String& shader,
|
||||
SkSL::Program::Kind kind,
|
||||
SkSL::ProgramKind kind,
|
||||
const SkSL::Program::Settings& settings,
|
||||
SkSL::String* msl,
|
||||
SkSL::Program::Inputs* inputs,
|
||||
@ -433,14 +433,14 @@ GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(GrRenderTarget* renderTa
|
||||
|
||||
shaderLibraries[kVertex_GrShaderType] = this->generateMtlShaderLibrary(
|
||||
*sksl[kVertex_GrShaderType],
|
||||
SkSL::Program::kVertex_Kind,
|
||||
SkSL::ProgramKind::kVertex,
|
||||
settings,
|
||||
&shaders[kVertex_GrShaderType],
|
||||
&inputs[kVertex_GrShaderType],
|
||||
errorHandler);
|
||||
shaderLibraries[kFragment_GrShaderType] = this->generateMtlShaderLibrary(
|
||||
*sksl[kFragment_GrShaderType],
|
||||
SkSL::Program::kFragment_Kind,
|
||||
SkSL::ProgramKind::kFragment,
|
||||
settings,
|
||||
&shaders[kFragment_GrShaderType],
|
||||
&inputs[kFragment_GrShaderType],
|
||||
|
@ -70,7 +70,7 @@ MTLTextureDescriptor* GrGetMTLTextureDescriptor(id<MTLTexture> mtlTexture);
|
||||
*/
|
||||
id<MTLLibrary> GrGenerateMtlShaderLibrary(const GrMtlGpu* gpu,
|
||||
const SkSL::String& sksl,
|
||||
SkSL::Program::Kind kind,
|
||||
SkSL::ProgramKind kind,
|
||||
const SkSL::Program::Settings& settings,
|
||||
SkSL::String* msl,
|
||||
SkSL::Program::Inputs* outInputs,
|
||||
|
@ -53,7 +53,7 @@ static const bool gPrintMSL = false;
|
||||
|
||||
id<MTLLibrary> GrGenerateMtlShaderLibrary(const GrMtlGpu* gpu,
|
||||
const SkSL::String& sksl,
|
||||
SkSL::Program::Kind programKind,
|
||||
SkSL::ProgramKind programKind,
|
||||
const SkSL::Program::Settings& settings,
|
||||
SkSL::String* msl,
|
||||
SkSL::Program::Inputs* outInputs,
|
||||
|
@ -74,15 +74,15 @@ bool GrSampleCountToVkSampleCount(uint32_t samples, VkSampleCountFlagBits* vkSam
|
||||
}
|
||||
}
|
||||
|
||||
SkSL::Program::Kind vk_shader_stage_to_skiasl_kind(VkShaderStageFlagBits stage) {
|
||||
SkSL::ProgramKind vk_shader_stage_to_skiasl_kind(VkShaderStageFlagBits stage) {
|
||||
if (VK_SHADER_STAGE_VERTEX_BIT == stage) {
|
||||
return SkSL::Program::kVertex_Kind;
|
||||
return SkSL::ProgramKind::kVertex;
|
||||
}
|
||||
if (VK_SHADER_STAGE_GEOMETRY_BIT == stage) {
|
||||
return SkSL::Program::kGeometry_Kind;
|
||||
return SkSL::ProgramKind::kGeometry;
|
||||
}
|
||||
SkASSERT(VK_SHADER_STAGE_FRAGMENT_BIT == stage);
|
||||
return SkSL::Program::kFragment_Kind;
|
||||
return SkSL::ProgramKind::kFragment;
|
||||
}
|
||||
|
||||
bool GrCompileVkShaderModule(GrVkGpu* gpu,
|
||||
|
@ -174,14 +174,14 @@ Compiler::~Compiler() {}
|
||||
|
||||
const ParsedModule& Compiler::loadGPUModule() {
|
||||
if (!fGPUModule.fSymbols) {
|
||||
fGPUModule = this->parseModule(Program::kFragment_Kind, MODULE_DATA(gpu), fPrivateModule);
|
||||
fGPUModule = this->parseModule(ProgramKind::kFragment, MODULE_DATA(gpu), fPrivateModule);
|
||||
}
|
||||
return fGPUModule;
|
||||
}
|
||||
|
||||
const ParsedModule& Compiler::loadFragmentModule() {
|
||||
if (!fFragmentModule.fSymbols) {
|
||||
fFragmentModule = this->parseModule(Program::kFragment_Kind, MODULE_DATA(frag),
|
||||
fFragmentModule = this->parseModule(ProgramKind::kFragment, MODULE_DATA(frag),
|
||||
this->loadGPUModule());
|
||||
}
|
||||
return fFragmentModule;
|
||||
@ -189,7 +189,7 @@ const ParsedModule& Compiler::loadFragmentModule() {
|
||||
|
||||
const ParsedModule& Compiler::loadVertexModule() {
|
||||
if (!fVertexModule.fSymbols) {
|
||||
fVertexModule = this->parseModule(Program::kVertex_Kind, MODULE_DATA(vert),
|
||||
fVertexModule = this->parseModule(ProgramKind::kVertex, MODULE_DATA(vert),
|
||||
this->loadGPUModule());
|
||||
}
|
||||
return fVertexModule;
|
||||
@ -197,7 +197,7 @@ const ParsedModule& Compiler::loadVertexModule() {
|
||||
|
||||
const ParsedModule& Compiler::loadGeometryModule() {
|
||||
if (!fGeometryModule.fSymbols) {
|
||||
fGeometryModule = this->parseModule(Program::kGeometry_Kind, MODULE_DATA(geom),
|
||||
fGeometryModule = this->parseModule(ProgramKind::kGeometry, MODULE_DATA(geom),
|
||||
this->loadGPUModule());
|
||||
}
|
||||
return fGeometryModule;
|
||||
@ -205,7 +205,7 @@ const ParsedModule& Compiler::loadGeometryModule() {
|
||||
|
||||
const ParsedModule& Compiler::loadFPModule() {
|
||||
if (!fFPModule.fSymbols) {
|
||||
fFPModule = this->parseModule(Program::kFragmentProcessor_Kind, MODULE_DATA(fp),
|
||||
fFPModule = this->parseModule(ProgramKind::kFragmentProcessor, MODULE_DATA(fp),
|
||||
this->loadGPUModule());
|
||||
}
|
||||
return fFPModule;
|
||||
@ -213,14 +213,14 @@ const ParsedModule& Compiler::loadFPModule() {
|
||||
|
||||
const ParsedModule& Compiler::loadPublicModule() {
|
||||
if (!fPublicModule.fSymbols) {
|
||||
fPublicModule = this->parseModule(Program::kGeneric_Kind, MODULE_DATA(public), fRootModule);
|
||||
fPublicModule = this->parseModule(ProgramKind::kGeneric, MODULE_DATA(public), fRootModule);
|
||||
}
|
||||
return fPublicModule;
|
||||
}
|
||||
|
||||
const ParsedModule& Compiler::loadRuntimeEffectModule() {
|
||||
if (!fRuntimeEffectModule.fSymbols) {
|
||||
fRuntimeEffectModule = this->parseModule(Program::kRuntimeEffect_Kind, MODULE_DATA(runtime),
|
||||
fRuntimeEffectModule = this->parseModule(ProgramKind::kRuntimeEffect, MODULE_DATA(runtime),
|
||||
this->loadPublicModule());
|
||||
|
||||
// Add some aliases to the runtime effect module so that it's friendlier, and more like GLSL
|
||||
@ -241,19 +241,19 @@ const ParsedModule& Compiler::loadRuntimeEffectModule() {
|
||||
return fRuntimeEffectModule;
|
||||
}
|
||||
|
||||
const ParsedModule& Compiler::moduleForProgramKind(Program::Kind kind) {
|
||||
const ParsedModule& Compiler::moduleForProgramKind(ProgramKind kind) {
|
||||
switch (kind) {
|
||||
case Program::kVertex_Kind: return this->loadVertexModule(); break;
|
||||
case Program::kFragment_Kind: return this->loadFragmentModule(); break;
|
||||
case Program::kGeometry_Kind: return this->loadGeometryModule(); break;
|
||||
case Program::kFragmentProcessor_Kind: return this->loadFPModule(); break;
|
||||
case Program::kRuntimeEffect_Kind: return this->loadRuntimeEffectModule(); break;
|
||||
case Program::kGeneric_Kind: return this->loadPublicModule(); break;
|
||||
case ProgramKind::kVertex: return this->loadVertexModule(); break;
|
||||
case ProgramKind::kFragment: return this->loadFragmentModule(); break;
|
||||
case ProgramKind::kGeometry: return this->loadGeometryModule(); break;
|
||||
case ProgramKind::kFragmentProcessor: return this->loadFPModule(); break;
|
||||
case ProgramKind::kRuntimeEffect: return this->loadRuntimeEffectModule(); break;
|
||||
case ProgramKind::kGeneric: return this->loadPublicModule(); break;
|
||||
}
|
||||
SkUNREACHABLE;
|
||||
}
|
||||
|
||||
LoadedModule Compiler::loadModule(Program::Kind kind,
|
||||
LoadedModule Compiler::loadModule(ProgramKind kind,
|
||||
ModuleData data,
|
||||
std::shared_ptr<SymbolTable> base) {
|
||||
if (!base) {
|
||||
@ -281,6 +281,7 @@ LoadedModule Compiler::loadModule(Program::Kind kind,
|
||||
SkASSERT(fIRGenerator->fCanInline);
|
||||
fIRGenerator->fCanInline = false;
|
||||
settings.fReplaceSettings = false;
|
||||
|
||||
ParsedModule baseModule = {base, /*fIntrinsics=*/nullptr};
|
||||
IRGenerator::IRBundle ir =
|
||||
fIRGenerator->convertProgram(kind, &settings, baseModule,
|
||||
@ -305,7 +306,7 @@ LoadedModule Compiler::loadModule(Program::Kind kind,
|
||||
return module;
|
||||
}
|
||||
|
||||
ParsedModule Compiler::parseModule(Program::Kind kind, ModuleData data, const ParsedModule& base) {
|
||||
ParsedModule Compiler::parseModule(ProgramKind kind, ModuleData data, const ParsedModule& base) {
|
||||
LoadedModule module = this->loadModule(kind, data, base.fSymbols);
|
||||
this->optimize(module);
|
||||
|
||||
@ -1564,11 +1565,11 @@ bool Compiler::scanCFG(FunctionDefinition& f, ProgramUsage* usage) {
|
||||
}
|
||||
|
||||
std::unique_ptr<Program> Compiler::convertProgram(
|
||||
Program::Kind kind,
|
||||
ProgramKind kind,
|
||||
String text,
|
||||
const Program::Settings& settings,
|
||||
const std::vector<std::unique_ptr<ExternalFunction>>* externalFunctions) {
|
||||
SkASSERT(!externalFunctions || (kind == Program::kGeneric_Kind));
|
||||
SkASSERT(!externalFunctions || (kind == ProgramKind::kGeneric));
|
||||
|
||||
// Loading and optimizing our base module might reset the inliner, so do that first,
|
||||
// *then* configure the inliner with the settings for this program.
|
||||
@ -1745,7 +1746,7 @@ bool Compiler::optimize(Program& program) {
|
||||
program.fSharedElements.end());
|
||||
}
|
||||
|
||||
if (program.fKind != Program::kFragmentProcessor_Kind) {
|
||||
if (program.fKind != ProgramKind::kFragmentProcessor) {
|
||||
// Remove declarations of dead global variables
|
||||
auto isDeadVariable = [&](const ProgramElement* element) {
|
||||
if (!element->is<GlobalVarDeclaration>()) {
|
||||
|
@ -55,7 +55,7 @@ class IRIntrinsicMap;
|
||||
class ProgramUsage;
|
||||
|
||||
struct LoadedModule {
|
||||
Program::Kind fKind;
|
||||
ProgramKind fKind;
|
||||
std::shared_ptr<SymbolTable> fSymbols;
|
||||
std::vector<std::unique_ptr<ProgramElement>> fElements;
|
||||
};
|
||||
@ -103,7 +103,7 @@ public:
|
||||
* Program, but ownership is *not* transferred. It is up to the caller to keep them alive.
|
||||
*/
|
||||
std::unique_ptr<Program> convertProgram(
|
||||
Program::Kind kind,
|
||||
ProgramKind kind,
|
||||
String text,
|
||||
const Program::Settings& settings,
|
||||
const std::vector<std::unique_ptr<ExternalFunction>>* externalFunctions = nullptr);
|
||||
@ -160,14 +160,14 @@ public:
|
||||
return ModuleData{/*fPath=*/nullptr, data, size};
|
||||
}
|
||||
|
||||
LoadedModule loadModule(Program::Kind kind, ModuleData data, std::shared_ptr<SymbolTable> base);
|
||||
ParsedModule parseModule(Program::Kind kind, ModuleData data, const ParsedModule& base);
|
||||
LoadedModule loadModule(ProgramKind kind, ModuleData data, std::shared_ptr<SymbolTable> base);
|
||||
ParsedModule parseModule(ProgramKind kind, ModuleData data, const ParsedModule& base);
|
||||
|
||||
IRGenerator& irGenerator() {
|
||||
return *fIRGenerator;
|
||||
}
|
||||
|
||||
const ParsedModule& moduleForProgramKind(Program::Kind kind);
|
||||
const ParsedModule& moduleForProgramKind(ProgramKind kind);
|
||||
|
||||
private:
|
||||
const ParsedModule& loadGPUModule();
|
||||
|
@ -17,6 +17,9 @@
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
struct ProgramSettings;
|
||||
enum class ProgramKind : int8_t;
|
||||
|
||||
/**
|
||||
* Contains compiler-wide objects, which currently means the core types.
|
||||
*/
|
||||
|
@ -873,7 +873,7 @@ void GLSLCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
|
||||
if (precedence >= parentPrecedence) {
|
||||
this->write("(");
|
||||
}
|
||||
bool positionWorkaround = fProgramKind == Program::Kind::kVertex_Kind &&
|
||||
bool positionWorkaround = fProgramKind == ProgramKind::kVertex &&
|
||||
op.isAssignment() &&
|
||||
left.is<FieldAccess>() &&
|
||||
is_sk_position(left.as<FieldAccess>()) &&
|
||||
@ -1082,8 +1082,8 @@ void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers,
|
||||
} else if (modifiers.fFlags & Modifiers::kIn_Flag) {
|
||||
if (globalContext &&
|
||||
fProgram.fCaps->generation() < GrGLSLGeneration::k130_GrGLSLGeneration) {
|
||||
this->write(fProgramKind == Program::kVertex_Kind ? "attribute "
|
||||
: "varying ");
|
||||
this->write(fProgramKind == ProgramKind::kVertex ? "attribute "
|
||||
: "varying ");
|
||||
} else {
|
||||
this->write("in ");
|
||||
}
|
||||
@ -1517,7 +1517,7 @@ void GLSLCodeGenerator::writeInputVars() {
|
||||
|
||||
bool GLSLCodeGenerator::generateCode() {
|
||||
this->writeHeader();
|
||||
if (Program::kGeometry_Kind == fProgramKind &&
|
||||
if (ProgramKind::kGeometry == fProgramKind &&
|
||||
fProgram.fCaps->geometryShaderExtensionString()) {
|
||||
this->writeExtension(fProgram.fCaps->geometryShaderExtensionString());
|
||||
}
|
||||
@ -1548,7 +1548,7 @@ bool GLSLCodeGenerator::generateCode() {
|
||||
if (!fProgram.fCaps->canUseFragCoord()) {
|
||||
Layout layout;
|
||||
switch (fProgram.fKind) {
|
||||
case Program::kVertex_Kind: {
|
||||
case ProgramKind::kVertex: {
|
||||
Modifiers modifiers(layout, Modifiers::kOut_Flag);
|
||||
this->writeModifiers(modifiers, true);
|
||||
if (this->usesPrecisionModifiers()) {
|
||||
@ -1557,7 +1557,7 @@ bool GLSLCodeGenerator::generateCode() {
|
||||
this->write("vec4 sk_FragCoord_Workaround;\n");
|
||||
break;
|
||||
}
|
||||
case Program::kFragment_Kind: {
|
||||
case ProgramKind::kFragment: {
|
||||
Modifiers modifiers(layout, Modifiers::kIn_Flag);
|
||||
this->writeModifiers(modifiers, true);
|
||||
if (this->usesPrecisionModifiers()) {
|
||||
|
@ -181,7 +181,7 @@ protected:
|
||||
StringStream fGlobals;
|
||||
StringStream fExtraFunctions;
|
||||
String fFunctionHeader;
|
||||
Program::Kind fProgramKind;
|
||||
ProgramKind fProgramKind;
|
||||
int fVarCount = 0;
|
||||
int fIndentation = 0;
|
||||
bool fAtLineStart = false;
|
||||
|
@ -78,9 +78,9 @@ public:
|
||||
std::shared_ptr<SymbolTable> fPrevious;
|
||||
};
|
||||
|
||||
static void fill_caps(const SkSL::ShaderCapsClass& caps,
|
||||
std::unordered_map<String, Program::Settings::Value>* capsMap) {
|
||||
#define CAP(name) capsMap->insert({String(#name), Program::Settings::Value(caps.name())})
|
||||
void IRGenerator::FillCapsMap(const SkSL::ShaderCapsClass& caps,
|
||||
std::unordered_map<String, CapsValue>* capsMap) {
|
||||
#define CAP(name) capsMap->insert({String(#name), CapsValue(caps.name())})
|
||||
CAP(fbFetchSupport);
|
||||
CAP(fbFetchNeedsCustomOutput);
|
||||
CAP(flatInterpolationSupport);
|
||||
@ -101,15 +101,33 @@ static void fill_caps(const SkSL::ShaderCapsClass& caps,
|
||||
#undef CAP
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> IRGenerator::CapsValue::literal(const Context& context,
|
||||
int offset) const {
|
||||
switch (fKind) {
|
||||
case kBool_Kind:
|
||||
return std::make_unique<BoolLiteral>(context, offset, fValue);
|
||||
|
||||
case kInt_Kind:
|
||||
return std::make_unique<IntLiteral>(context, offset, fValue);
|
||||
|
||||
case kFloat_Kind:
|
||||
return std::make_unique<FloatLiteral>(context, offset, fValueF);
|
||||
|
||||
default:
|
||||
SkDEBUGFAILF("unrecognized caps kind: %d", fKind);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
IRGenerator::IRGenerator(const Context* context,
|
||||
const ShaderCapsClass* caps)
|
||||
: fContext(*context)
|
||||
, fCaps(caps)
|
||||
, fModifiers(new ModifiersPool()) {
|
||||
if (fCaps) {
|
||||
fill_caps(*fCaps, &fCapsMap);
|
||||
FillCapsMap(*fCaps, &fCapsMap);
|
||||
} else {
|
||||
fCapsMap.insert({String("integerSupport"), Program::Settings::Value(true)});
|
||||
fCapsMap.insert({String("integerSupport"), CapsValue(true)});
|
||||
}
|
||||
|
||||
}
|
||||
@ -156,9 +174,9 @@ bool IRGenerator::detectVarDeclarationWithoutScope(const Statement& stmt) {
|
||||
}
|
||||
|
||||
std::unique_ptr<Extension> IRGenerator::convertExtension(int offset, StringFragment name) {
|
||||
if (fKind != Program::kFragment_Kind &&
|
||||
fKind != Program::kVertex_Kind &&
|
||||
fKind != Program::kGeometry_Kind) {
|
||||
if (fKind != ProgramKind::kFragment &&
|
||||
fKind != ProgramKind::kVertex &&
|
||||
fKind != ProgramKind::kGeometry) {
|
||||
this->errorReporter().error(offset, "extensions are not allowed here");
|
||||
return nullptr;
|
||||
}
|
||||
@ -202,7 +220,7 @@ std::unique_ptr<Statement> IRGenerator::convertSingleStatement(const ASTNode& st
|
||||
default:
|
||||
// it's an expression
|
||||
std::unique_ptr<Statement> result = this->convertExpressionStatement(statement);
|
||||
if (fRTAdjust && fKind == Program::kGeometry_Kind) {
|
||||
if (fRTAdjust && fKind == ProgramKind::kGeometry) {
|
||||
SkASSERT(result->kind() == Statement::Kind::kExpression);
|
||||
Expression& expr = *result->as<ExpressionStatement>().expression();
|
||||
if (expr.kind() == Expression::Kind::kFunctionCall) {
|
||||
@ -320,7 +338,7 @@ void IRGenerator::checkVarDeclaration(int offset, const Modifiers& modifiers, co
|
||||
offset,
|
||||
"variables of type '" + baseType->displayName() + "' must be global");
|
||||
}
|
||||
if (fKind != Program::kFragmentProcessor_Kind) {
|
||||
if (fKind != ProgramKind::kFragmentProcessor) {
|
||||
if ((modifiers.fFlags & Modifiers::kIn_Flag) && baseType->isMatrix()) {
|
||||
this->errorReporter().error(offset, "'in' variables may not have matrix type");
|
||||
}
|
||||
@ -347,7 +365,7 @@ void IRGenerator::checkVarDeclaration(int offset, const Modifiers& modifiers, co
|
||||
"'key' is only permitted within fragment processors");
|
||||
}
|
||||
}
|
||||
if (fKind == Program::kRuntimeEffect_Kind) {
|
||||
if (fKind == ProgramKind::kRuntimeEffect) {
|
||||
if ((modifiers.fFlags & Modifiers::kIn_Flag) &&
|
||||
*baseType != *fContext.fTypes.fFragmentProcessor) {
|
||||
this->errorReporter().error(offset,
|
||||
@ -358,7 +376,7 @@ void IRGenerator::checkVarDeclaration(int offset, const Modifiers& modifiers, co
|
||||
this->errorReporter().error(offset, "'key' is not permitted on 'uniform' variables");
|
||||
}
|
||||
if (modifiers.fLayout.fMarker.fLength) {
|
||||
if (fKind != Program::kRuntimeEffect_Kind) {
|
||||
if (fKind != ProgramKind::kRuntimeEffect) {
|
||||
this->errorReporter().error(offset,
|
||||
"'marker' is only permitted in runtime effects");
|
||||
}
|
||||
@ -372,7 +390,7 @@ void IRGenerator::checkVarDeclaration(int offset, const Modifiers& modifiers, co
|
||||
}
|
||||
}
|
||||
if (modifiers.fLayout.fFlags & Layout::kSRGBUnpremul_Flag) {
|
||||
if (fKind != Program::kRuntimeEffect_Kind) {
|
||||
if (fKind != ProgramKind::kRuntimeEffect) {
|
||||
this->errorReporter().error(offset,
|
||||
"'srgb_unpremul' is only permitted in runtime effects");
|
||||
}
|
||||
@ -392,7 +410,7 @@ void IRGenerator::checkVarDeclaration(int offset, const Modifiers& modifiers, co
|
||||
}
|
||||
}
|
||||
if (modifiers.fFlags & Modifiers::kVarying_Flag) {
|
||||
if (fKind != Program::kRuntimeEffect_Kind) {
|
||||
if (fKind != ProgramKind::kRuntimeEffect) {
|
||||
this->errorReporter().error(offset, "'varying' is only permitted in runtime effects");
|
||||
}
|
||||
if (!baseType->isFloat() &&
|
||||
@ -422,7 +440,7 @@ std::unique_ptr<Statement> IRGenerator::convertVarDeclaration(int offset,
|
||||
std::unique_ptr<Expression> value,
|
||||
Variable::Storage storage) {
|
||||
if (modifiers.fLayout.fLocation == 0 && modifiers.fLayout.fIndex == 0 &&
|
||||
(modifiers.fFlags & Modifiers::kOut_Flag) && fKind == Program::kFragment_Kind &&
|
||||
(modifiers.fFlags & Modifiers::kOut_Flag) && fKind == ProgramKind::kFragment &&
|
||||
name != "sk_FragColor") {
|
||||
this->errorReporter().error(offset,
|
||||
"out location=0, index=0 is reserved for sk_FragColor");
|
||||
@ -522,9 +540,9 @@ StatementArray IRGenerator::convertVarDeclarations(const ASTNode& decls,
|
||||
}
|
||||
|
||||
std::unique_ptr<ModifiersDeclaration> IRGenerator::convertModifiersDeclaration(const ASTNode& m) {
|
||||
if (fKind != Program::kFragment_Kind &&
|
||||
fKind != Program::kVertex_Kind &&
|
||||
fKind != Program::kGeometry_Kind) {
|
||||
if (fKind != ProgramKind::kFragment &&
|
||||
fKind != ProgramKind::kVertex &&
|
||||
fKind != ProgramKind::kGeometry) {
|
||||
this->errorReporter().error(m.fOffset, "layout qualifiers are not allowed here");
|
||||
return nullptr;
|
||||
}
|
||||
@ -532,7 +550,7 @@ std::unique_ptr<ModifiersDeclaration> IRGenerator::convertModifiersDeclaration(c
|
||||
SkASSERT(m.fKind == ASTNode::Kind::kModifiers);
|
||||
Modifiers modifiers = m.getModifiers();
|
||||
if (modifiers.fLayout.fInvocations != -1) {
|
||||
if (fKind != Program::kGeometry_Kind) {
|
||||
if (fKind != ProgramKind::kGeometry) {
|
||||
this->errorReporter().error(m.fOffset,
|
||||
"'invocations' is only legal in geometry shaders");
|
||||
return nullptr;
|
||||
@ -858,7 +876,7 @@ std::unique_ptr<Statement> IRGenerator::convertContinue(const ASTNode& c) {
|
||||
|
||||
std::unique_ptr<Statement> IRGenerator::convertDiscard(const ASTNode& d) {
|
||||
SkASSERT(d.fKind == ASTNode::Kind::kDiscard);
|
||||
if (fKind != Program::kFragment_Kind && fKind != Program::kFragmentProcessor_Kind) {
|
||||
if (fKind != ProgramKind::kFragment && fKind != ProgramKind::kFragmentProcessor) {
|
||||
this->errorReporter().error(d.fOffset,
|
||||
"discard statement is only permitted in fragment shaders");
|
||||
return nullptr;
|
||||
@ -1052,7 +1070,7 @@ void IRGenerator::finalizeFunction(FunctionDefinition& f) {
|
||||
// normalization, so SkASSERT that we aren't doing that. It is of course
|
||||
// possible to fix this by adding a normalization before each return, but it
|
||||
// will probably never actually be necessary.
|
||||
SkASSERT(fIRGenerator->fKind != Program::kVertex_Kind ||
|
||||
SkASSERT(fIRGenerator->fKind != ProgramKind::kVertex ||
|
||||
!fIRGenerator->fRTAdjust ||
|
||||
fFunction->name() != "main");
|
||||
ReturnStatement& r = stmt.as<ReturnStatement>();
|
||||
@ -1170,8 +1188,8 @@ void IRGenerator::convertFunction(const ASTNode& f) {
|
||||
}
|
||||
|
||||
Modifiers m = pd.fModifiers;
|
||||
if (funcData.fName == "main" && (fKind == Program::kRuntimeEffect_Kind ||
|
||||
fKind == Program::kFragmentProcessor_Kind)) {
|
||||
if (funcData.fName == "main" && (fKind == ProgramKind::kRuntimeEffect ||
|
||||
fKind == ProgramKind::kFragmentProcessor)) {
|
||||
if (i == 0) {
|
||||
// We verify that the type is correct later, for now, if there is a parameter to
|
||||
// a .fp or runtime-effect main(), it's supposed to be the coords:
|
||||
@ -1193,7 +1211,7 @@ void IRGenerator::convertFunction(const ASTNode& f) {
|
||||
|
||||
if (funcData.fName == "main") {
|
||||
switch (fKind) {
|
||||
case Program::kRuntimeEffect_Kind: {
|
||||
case ProgramKind::kRuntimeEffect: {
|
||||
// (half4|float4) main() -or- (half4|float4) main(float2)
|
||||
if (*returnType != *fContext.fTypes.fHalf4 &&
|
||||
*returnType != *fContext.fTypes.fFloat4) {
|
||||
@ -1210,7 +1228,7 @@ void IRGenerator::convertFunction(const ASTNode& f) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Program::kFragmentProcessor_Kind: {
|
||||
case ProgramKind::kFragmentProcessor: {
|
||||
if (*returnType != *fContext.fTypes.fHalf4) {
|
||||
this->errorReporter().error(f.fOffset, ".fp 'main' must return 'half4'");
|
||||
return;
|
||||
@ -1224,7 +1242,7 @@ void IRGenerator::convertFunction(const ASTNode& f) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Program::kGeneric_Kind:
|
||||
case ProgramKind::kGeneric:
|
||||
break;
|
||||
default:
|
||||
if (parameters.size()) {
|
||||
@ -1330,7 +1348,7 @@ void IRGenerator::convertFunction(const ASTNode& f) {
|
||||
if (needInvocationIDWorkaround) {
|
||||
body = this->applyInvocationIDWorkaround(std::move(body));
|
||||
}
|
||||
if (Program::kVertex_Kind == fKind && funcData.fName == "main" && fRTAdjust) {
|
||||
if (ProgramKind::kVertex == fKind && funcData.fName == "main" && fRTAdjust) {
|
||||
body->children().push_back(this->getNormalizeSkPositionCode());
|
||||
}
|
||||
auto result = std::make_unique<FunctionDefinition>(
|
||||
@ -1360,9 +1378,9 @@ std::unique_ptr<StructDefinition> IRGenerator::convertStructDefinition(const AST
|
||||
}
|
||||
|
||||
std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTNode& intf) {
|
||||
if (fKind != Program::kFragment_Kind &&
|
||||
fKind != Program::kVertex_Kind &&
|
||||
fKind != Program::kGeometry_Kind) {
|
||||
if (fKind != ProgramKind::kFragment &&
|
||||
fKind != ProgramKind::kVertex &&
|
||||
fKind != ProgramKind::kGeometry) {
|
||||
this->errorReporter().error(intf.fOffset, "interface block is not allowed here");
|
||||
return nullptr;
|
||||
}
|
||||
@ -1631,7 +1649,7 @@ std::unique_ptr<Expression> IRGenerator::convertIdentifier(int offset, StringFra
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (fKind == Program::kFragmentProcessor_Kind &&
|
||||
if (fKind == ProgramKind::kFragmentProcessor &&
|
||||
(modifiers.fFlags & Modifiers::kIn_Flag) &&
|
||||
!(modifiers.fFlags & Modifiers::kUniform_Flag) &&
|
||||
!modifiers.fLayout.fKey &&
|
||||
@ -1686,7 +1704,7 @@ std::unique_ptr<Expression> IRGenerator::convertIdentifier(const ASTNode& identi
|
||||
}
|
||||
|
||||
std::unique_ptr<Section> IRGenerator::convertSection(const ASTNode& s) {
|
||||
if (fKind != Program::kFragmentProcessor_Kind) {
|
||||
if (fKind != ProgramKind::kFragmentProcessor) {
|
||||
this->errorReporter().error(s.fOffset, "syntax error");
|
||||
return nullptr;
|
||||
}
|
||||
@ -2640,9 +2658,9 @@ const Type* IRGenerator::typeForSetting(int offset, String name) const {
|
||||
return nullptr;
|
||||
}
|
||||
switch (found->second.fKind) {
|
||||
case Program::Settings::Value::kBool_Kind: return fContext.fTypes.fBool.get();
|
||||
case Program::Settings::Value::kFloat_Kind: return fContext.fTypes.fFloat.get();
|
||||
case Program::Settings::Value::kInt_Kind: return fContext.fTypes.fInt.get();
|
||||
case CapsValue::kBool_Kind: return fContext.fTypes.fBool.get();
|
||||
case CapsValue::kFloat_Kind: return fContext.fTypes.fFloat.get();
|
||||
case CapsValue::kInt_Kind: return fContext.fTypes.fInt.get();
|
||||
}
|
||||
SkUNREACHABLE;
|
||||
return nullptr;
|
||||
@ -2947,7 +2965,7 @@ void IRGenerator::findAndDeclareBuiltinVariables() {
|
||||
}
|
||||
|
||||
switch (fKind) {
|
||||
case Program::kFragment_Kind:
|
||||
case ProgramKind::kFragment:
|
||||
// Vulkan requires certain builtin variables be present, even if they're unused. At one
|
||||
// time, validation errors would result if sk_Clockwise was missing. Now, it's just
|
||||
// (Adreno) driver bugs that drop or corrupt draws if they're missing.
|
||||
@ -2962,7 +2980,7 @@ void IRGenerator::findAndDeclareBuiltinVariables() {
|
||||
}
|
||||
|
||||
IRGenerator::IRBundle IRGenerator::convertProgram(
|
||||
Program::Kind kind,
|
||||
ProgramKind kind,
|
||||
const Program::Settings* settings,
|
||||
const ParsedModule& base,
|
||||
bool isBuiltinCode,
|
||||
@ -2992,7 +3010,7 @@ IRGenerator::IRBundle IRGenerator::convertProgram(
|
||||
|
||||
AutoSymbolTable table(this);
|
||||
|
||||
if (kind == Program::kGeometry_Kind && !fIsBuiltinCode) {
|
||||
if (kind == ProgramKind::kGeometry && !fIsBuiltinCode) {
|
||||
// Declare sk_InvocationID programmatically. With invocations support, it's an 'in' builtin.
|
||||
// If we're applying the workaround, then it's a plain global.
|
||||
bool workaround = fCaps && !fCaps->gsInvocationsSupport();
|
||||
|
@ -121,7 +121,7 @@ public:
|
||||
* Program, but ownership is *not* transferred. It is up to the caller to keep them alive.
|
||||
*/
|
||||
IRBundle convertProgram(
|
||||
Program::Kind kind,
|
||||
ProgramKind kind,
|
||||
const Program::Settings* settings,
|
||||
const ParsedModule& base,
|
||||
bool isBuiltinCode,
|
||||
@ -281,16 +281,40 @@ private:
|
||||
// Runtime effects (and the interpreter, which uses the same CPU runtime) require adherence to
|
||||
// the strict rules from The OpenGL ES Shading Language Version 1.00. (Including Appendix A).
|
||||
bool strictES2Mode() const {
|
||||
return fKind == Program::kRuntimeEffect_Kind || fKind == Program::kGeneric_Kind;
|
||||
return fKind == ProgramKind::kRuntimeEffect || fKind == ProgramKind::kGeneric;
|
||||
}
|
||||
|
||||
Program::Inputs fInputs;
|
||||
const Program::Settings* fSettings = nullptr;
|
||||
const ShaderCapsClass* fCaps = nullptr;
|
||||
Program::Kind fKind;
|
||||
ProgramKind fKind;
|
||||
|
||||
std::unique_ptr<ASTFile> fFile;
|
||||
std::unordered_map<String, Program::Settings::Value> fCapsMap;
|
||||
|
||||
struct CapsValue {
|
||||
CapsValue(bool b) : fKind(kBool_Kind), fValue(b) {}
|
||||
CapsValue(int i) : fKind(kInt_Kind), fValue(i) {}
|
||||
CapsValue(unsigned int i) : fKind(kInt_Kind), fValue(i) {}
|
||||
CapsValue(float f) : fKind(kFloat_Kind), fValueF(f) {}
|
||||
|
||||
std::unique_ptr<Expression> literal(const Context& context, int offset) const;
|
||||
|
||||
enum {
|
||||
kBool_Kind,
|
||||
kInt_Kind,
|
||||
kFloat_Kind,
|
||||
} fKind;
|
||||
|
||||
union {
|
||||
int fValue; // for kBool_Kind and kInt_Kind
|
||||
float fValueF; // for kFloat_Kind
|
||||
};
|
||||
};
|
||||
|
||||
static void FillCapsMap(const SkSL::ShaderCapsClass& caps,
|
||||
std::unordered_map<String, CapsValue>* capsMap);
|
||||
|
||||
std::unordered_map<String, CapsValue> fCapsMap;
|
||||
std::shared_ptr<SymbolTable> fSymbolTable = nullptr;
|
||||
// additional statements that need to be inserted before the one that convertStatement is
|
||||
// currently working on
|
||||
|
@ -268,18 +268,18 @@ ResultCode processCommand(std::vector<SkSL::String>& args) {
|
||||
return ResultCode::kInputError;
|
||||
}
|
||||
|
||||
SkSL::Program::Kind kind;
|
||||
SkSL::ProgramKind kind;
|
||||
const SkSL::String& inputPath = args[1];
|
||||
if (inputPath.endsWith(".vert")) {
|
||||
kind = SkSL::Program::kVertex_Kind;
|
||||
kind = SkSL::ProgramKind::kVertex;
|
||||
} else if (inputPath.endsWith(".frag") || inputPath.endsWith(".sksl")) {
|
||||
kind = SkSL::Program::kFragment_Kind;
|
||||
kind = SkSL::ProgramKind::kFragment;
|
||||
} else if (inputPath.endsWith(".geom")) {
|
||||
kind = SkSL::Program::kGeometry_Kind;
|
||||
kind = SkSL::ProgramKind::kGeometry;
|
||||
} else if (inputPath.endsWith(".fp")) {
|
||||
kind = SkSL::Program::kFragmentProcessor_Kind;
|
||||
kind = SkSL::ProgramKind::kFragmentProcessor;
|
||||
} else if (inputPath.endsWith(".rte")) {
|
||||
kind = SkSL::Program::kRuntimeEffect_Kind;
|
||||
kind = SkSL::ProgramKind::kRuntimeEffect;
|
||||
} else {
|
||||
printf("input filename must end in '.vert', '.frag', '.geom', '.fp', '.rte', or '.sksl'\n");
|
||||
return ResultCode::kInputError;
|
||||
|
@ -1452,10 +1452,10 @@ bool MetalCodeGenerator::writeFunctionDeclaration(const FunctionDeclaration& f)
|
||||
const char* separator = "";
|
||||
if ("main" == f.name()) {
|
||||
switch (fProgram.fKind) {
|
||||
case Program::kFragment_Kind:
|
||||
case ProgramKind::kFragment:
|
||||
this->write("fragment Outputs fragmentMain");
|
||||
break;
|
||||
case Program::kVertex_Kind:
|
||||
case ProgramKind::kVertex:
|
||||
this->write("vertex Outputs vertexMain");
|
||||
break;
|
||||
default:
|
||||
@ -1508,14 +1508,14 @@ bool MetalCodeGenerator::writeFunctionDeclaration(const FunctionDeclaration& f)
|
||||
this->write(")]]");
|
||||
}
|
||||
}
|
||||
if (fProgram.fKind == Program::kFragment_Kind) {
|
||||
if (fProgram.fKind == ProgramKind::kFragment) {
|
||||
if (fProgram.fInputs.fRTHeight && fInterfaceBlockNameMap.empty()) {
|
||||
this->write(", constant sksl_synthetic_uniforms& _anonInterface0 [[buffer(1)]]");
|
||||
fRTHeightName = "_anonInterface0.u_skRTHeight";
|
||||
}
|
||||
this->write(", bool _frontFacing [[front_facing]]");
|
||||
this->write(", float4 _fragCoord [[position]]");
|
||||
} else if (fProgram.fKind == Program::kVertex_Kind) {
|
||||
} else if (fProgram.fKind == ProgramKind::kVertex) {
|
||||
this->write(", uint sk_VertexID [[vertex_id]], uint sk_InstanceID [[instance_id]]");
|
||||
}
|
||||
separator = ", ";
|
||||
@ -1871,10 +1871,10 @@ void MetalCodeGenerator::writeSwitchStatement(const SwitchStatement& s) {
|
||||
void MetalCodeGenerator::writeReturnStatementFromMain() {
|
||||
// main functions in Metal return a magic _out parameter that doesn't exist in SkSL.
|
||||
switch (fProgram.fKind) {
|
||||
case Program::kFragment_Kind:
|
||||
case ProgramKind::kFragment:
|
||||
this->write("return _out;");
|
||||
break;
|
||||
case Program::kVertex_Kind:
|
||||
case ProgramKind::kVertex:
|
||||
this->write("return (_out.sk_Position.y = -_out.sk_Position.y, _out);");
|
||||
break;
|
||||
default:
|
||||
@ -1954,10 +1954,10 @@ void MetalCodeGenerator::writeInputStruct() {
|
||||
this->write(" ");
|
||||
this->writeName(var.name());
|
||||
if (-1 != var.modifiers().fLayout.fLocation) {
|
||||
if (fProgram.fKind == Program::kVertex_Kind) {
|
||||
if (fProgram.fKind == ProgramKind::kVertex) {
|
||||
this->write(" [[attribute(" +
|
||||
to_string(var.modifiers().fLayout.fLocation) + ")]]");
|
||||
} else if (fProgram.fKind == Program::kFragment_Kind) {
|
||||
} else if (fProgram.fKind == ProgramKind::kFragment) {
|
||||
this->write(" [[user(locn" +
|
||||
to_string(var.modifiers().fLayout.fLocation) + ")]]");
|
||||
}
|
||||
@ -1971,9 +1971,9 @@ void MetalCodeGenerator::writeInputStruct() {
|
||||
|
||||
void MetalCodeGenerator::writeOutputStruct() {
|
||||
this->write("struct Outputs {\n");
|
||||
if (fProgram.fKind == Program::kVertex_Kind) {
|
||||
if (fProgram.fKind == ProgramKind::kVertex) {
|
||||
this->write(" float4 sk_Position [[position]];\n");
|
||||
} else if (fProgram.fKind == Program::kFragment_Kind) {
|
||||
} else if (fProgram.fKind == ProgramKind::kFragment) {
|
||||
this->write(" float4 sk_FragColor [[color(0)]];\n");
|
||||
}
|
||||
for (const ProgramElement* e : fProgram.elements()) {
|
||||
@ -1991,9 +1991,9 @@ void MetalCodeGenerator::writeOutputStruct() {
|
||||
if (location < 0) {
|
||||
fErrors.error(var.fOffset,
|
||||
"Metal out variables must have 'layout(location=...)'");
|
||||
} else if (fProgram.fKind == Program::kVertex_Kind) {
|
||||
} else if (fProgram.fKind == ProgramKind::kVertex) {
|
||||
this->write(" [[user(locn" + to_string(location) + ")]]");
|
||||
} else if (fProgram.fKind == Program::kFragment_Kind) {
|
||||
} else if (fProgram.fKind == ProgramKind::kFragment) {
|
||||
this->write(" [[color(" + to_string(location) + ")");
|
||||
int colorIndex = var.modifiers().fLayout.fIndex;
|
||||
if (colorIndex) {
|
||||
@ -2005,7 +2005,7 @@ void MetalCodeGenerator::writeOutputStruct() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fProgram.fKind == Program::kVertex_Kind) {
|
||||
if (fProgram.fKind == ProgramKind::kVertex) {
|
||||
this->write(" float sk_PointSize [[point_size]];\n");
|
||||
}
|
||||
this->write("};\n");
|
||||
|
@ -289,7 +289,7 @@ protected:
|
||||
const Context& fContext;
|
||||
String fFunctionHeader;
|
||||
StringStream fExtraFunctions;
|
||||
Program::Kind fProgramKind;
|
||||
ProgramKind fProgramKind;
|
||||
int fVarCount = 0;
|
||||
int fIndentation = 0;
|
||||
bool fAtLineStart = false;
|
||||
|
@ -375,7 +375,7 @@ void SPIRVCodeGenerator::writeCapabilities(OutputStream& out) {
|
||||
this->writeInstruction(SpvOpCapability, (SpvId) i, out);
|
||||
}
|
||||
}
|
||||
if (fProgram.fKind == Program::kGeometry_Kind) {
|
||||
if (fProgram.fKind == ProgramKind::kGeometry) {
|
||||
this->writeInstruction(SpvOpCapability, SpvCapabilityGeometry, out);
|
||||
}
|
||||
else {
|
||||
@ -2884,7 +2884,7 @@ static bool is_dead(const Variable& var, const ProgramUsage* usage) {
|
||||
return var.modifiers().fLayout.fBuiltin == SK_SAMPLEMASK_BUILTIN;
|
||||
}
|
||||
|
||||
void SPIRVCodeGenerator::writeGlobalVar(Program::Kind kind, const VarDeclaration& varDecl) {
|
||||
void SPIRVCodeGenerator::writeGlobalVar(ProgramKind kind, const VarDeclaration& varDecl) {
|
||||
const Variable& var = varDecl.var();
|
||||
// These haven't been implemented in our SPIR-V generator yet and we only currently use them
|
||||
// in the OpenGL backend.
|
||||
@ -2900,7 +2900,7 @@ void SPIRVCodeGenerator::writeGlobalVar(Program::Kind kind, const VarDeclaration
|
||||
return;
|
||||
}
|
||||
if (var.modifiers().fLayout.fBuiltin == SK_FRAGCOLOR_BUILTIN &&
|
||||
kind != Program::kFragment_Kind) {
|
||||
kind != ProgramKind::kFragment) {
|
||||
SkASSERT(!fProgram.fSettings.fFragColorIsInOut);
|
||||
return;
|
||||
}
|
||||
@ -3165,7 +3165,7 @@ void SPIRVCodeGenerator::writeReturnStatement(const ReturnStatement& r, OutputSt
|
||||
}
|
||||
|
||||
void SPIRVCodeGenerator::writeGeometryShaderExecutionMode(SpvId entryPoint, OutputStream& out) {
|
||||
SkASSERT(fProgram.fKind == Program::kGeometry_Kind);
|
||||
SkASSERT(fProgram.fKind == ProgramKind::kGeometry);
|
||||
int invocations = 1;
|
||||
for (const ProgramElement* e : fProgram.elements()) {
|
||||
if (e->is<ModifiersDeclaration>()) {
|
||||
@ -3408,13 +3408,13 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
|
||||
this->writeOpCode(SpvOpEntryPoint, (SpvId) (3 + (main->name().fLength + 4) / 4) +
|
||||
(int32_t) interfaceVars.size(), out);
|
||||
switch (program.fKind) {
|
||||
case Program::kVertex_Kind:
|
||||
case ProgramKind::kVertex:
|
||||
this->writeWord(SpvExecutionModelVertex, out);
|
||||
break;
|
||||
case Program::kFragment_Kind:
|
||||
case ProgramKind::kFragment:
|
||||
this->writeWord(SpvExecutionModelFragment, out);
|
||||
break;
|
||||
case Program::kGeometry_Kind:
|
||||
case ProgramKind::kGeometry:
|
||||
this->writeWord(SpvExecutionModelGeometry, out);
|
||||
break;
|
||||
default:
|
||||
@ -3426,10 +3426,10 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
|
||||
for (int var : interfaceVars) {
|
||||
this->writeWord(var, out);
|
||||
}
|
||||
if (program.fKind == Program::kGeometry_Kind) {
|
||||
if (program.fKind == ProgramKind::kGeometry) {
|
||||
this->writeGeometryShaderExecutionMode(entryPoint, out);
|
||||
}
|
||||
if (program.fKind == Program::kFragment_Kind) {
|
||||
if (program.fKind == ProgramKind::kFragment) {
|
||||
this->writeInstruction(SpvOpExecutionMode,
|
||||
fFunctionMap[main],
|
||||
SpvExecutionModeOriginUpperLeft,
|
||||
|
@ -201,7 +201,7 @@ private:
|
||||
|
||||
SpvId writeFunction(const FunctionDefinition& f, OutputStream& out);
|
||||
|
||||
void writeGlobalVar(Program::Kind kind, const VarDeclaration& v);
|
||||
void writeGlobalVar(ProgramKind kind, const VarDeclaration& v);
|
||||
|
||||
void writeVarDeclaration(const VarDeclaration& var, OutputStream& out);
|
||||
|
||||
|
@ -25,7 +25,7 @@ namespace dsl {
|
||||
|
||||
DSLWriter::DSLWriter(SkSL::Compiler* compiler)
|
||||
: fCompiler(compiler) {
|
||||
SkSL::ParsedModule module = fCompiler->moduleForProgramKind(SkSL::Program::kFragment_Kind);
|
||||
SkSL::ParsedModule module = fCompiler->moduleForProgramKind(SkSL::ProgramKind::kFragment);
|
||||
SkSL::IRGenerator& ir = *fCompiler->fIRGenerator;
|
||||
ir.fSymbolTable = module.fSymbols;
|
||||
ir.fSettings = &fSettings;
|
||||
|
@ -58,104 +58,72 @@ public:
|
||||
SkTHashMap<const FunctionDeclaration*, int> fCallCounts;
|
||||
};
|
||||
|
||||
/**
|
||||
* Holds the compiler settings for a program.
|
||||
*/
|
||||
struct ProgramSettings {
|
||||
// if false, sk_FragCoord is exactly the same as gl_FragCoord. If true, the y coordinate
|
||||
// must be flipped.
|
||||
bool fFlipY = false;
|
||||
// If true the destination fragment color is read sk_FragColor. It must be declared inout.
|
||||
bool fFragColorIsInOut = false;
|
||||
// if true, Setting objects (e.g. sk_Caps.fbFetchSupport) should be replaced with their
|
||||
// constant equivalents during compilation
|
||||
bool fReplaceSettings = true;
|
||||
// if true, all halfs are forced to be floats
|
||||
bool fForceHighPrecision = false;
|
||||
// if true, add -0.5 bias to LOD of all texture lookups
|
||||
bool fSharpenTextures = false;
|
||||
// if the program needs to create an RTHeight uniform, this is its offset in the uniform
|
||||
// buffer
|
||||
int fRTHeightOffset = -1;
|
||||
// if the program needs to create an RTHeight uniform and is creating spriv, this is the
|
||||
// binding and set number of the uniform buffer.
|
||||
int fRTHeightBinding = -1;
|
||||
int fRTHeightSet = -1;
|
||||
// If layout(set=S, binding=B) is not specified for a uniform, these values will be used.
|
||||
// At present, zero is always used by our backends.
|
||||
int fDefaultUniformSet = 0;
|
||||
int fDefaultUniformBinding = 0;
|
||||
// If true, remove any uncalled functions other than main(). Note that a function which
|
||||
// starts out being used may end up being uncalled after optimization.
|
||||
bool fRemoveDeadFunctions = true;
|
||||
// Sets an upper limit on the acceptable amount of code growth from inlining.
|
||||
// A value of zero will disable the inliner entirely.
|
||||
int fInlineThreshold = SkSL::kDefaultInlineThreshold;
|
||||
// true to enable optimization passes
|
||||
bool fOptimize = true;
|
||||
// If true, implicit conversions to lower precision numeric types are allowed
|
||||
// (eg, float to half)
|
||||
bool fAllowNarrowingConversions = false;
|
||||
// If true, then Debug code will run SPIR-V output through the validator to ensure its
|
||||
// correctness
|
||||
bool fValidateSPIRV = true;
|
||||
// If true, any synthetic uniforms must use push constant syntax
|
||||
bool fUsePushConstants = false;
|
||||
// Permits static if/switch statements to be used with non-constant tests. This is used when
|
||||
// producing H and CPP code; the static tests don't have to have constant values *yet*, but
|
||||
// the generated code will contain a static test which then does have to be a constant.
|
||||
bool fPermitInvalidStaticTests = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* SkSL supports several different program kinds.
|
||||
*/
|
||||
enum class ProgramKind : int8_t {
|
||||
kFragment,
|
||||
kVertex,
|
||||
kGeometry,
|
||||
kFragmentProcessor,
|
||||
kRuntimeEffect,
|
||||
kGeneric,
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a fully-digested program, ready for code generation.
|
||||
*/
|
||||
struct Program {
|
||||
struct Settings {
|
||||
struct Value {
|
||||
Value(bool b)
|
||||
: fKind(kBool_Kind)
|
||||
, fValue(b) {}
|
||||
|
||||
Value(int i)
|
||||
: fKind(kInt_Kind)
|
||||
, fValue(i) {}
|
||||
|
||||
Value(unsigned int i)
|
||||
: fKind(kInt_Kind)
|
||||
, fValue(i) {}
|
||||
|
||||
Value(float f)
|
||||
: fKind(kFloat_Kind)
|
||||
, fValueF(f) {}
|
||||
|
||||
std::unique_ptr<Expression> literal(const Context& context, int offset) const {
|
||||
switch (fKind) {
|
||||
case Program::Settings::Value::kBool_Kind:
|
||||
return std::unique_ptr<Expression>(new BoolLiteral(context,
|
||||
offset,
|
||||
fValue));
|
||||
case Program::Settings::Value::kInt_Kind:
|
||||
return std::unique_ptr<Expression>(new IntLiteral(context,
|
||||
offset,
|
||||
fValue));
|
||||
case Program::Settings::Value::kFloat_Kind:
|
||||
return std::unique_ptr<Expression>(new FloatLiteral(context,
|
||||
offset,
|
||||
fValueF));
|
||||
default:
|
||||
SkASSERT(false);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
enum {
|
||||
kBool_Kind,
|
||||
kInt_Kind,
|
||||
kFloat_Kind,
|
||||
} fKind;
|
||||
|
||||
union {
|
||||
int fValue; // for kBool_Kind and kInt_Kind
|
||||
float fValueF; // for kFloat_Kind
|
||||
};
|
||||
};
|
||||
|
||||
// if false, sk_FragCoord is exactly the same as gl_FragCoord. If true, the y coordinate
|
||||
// must be flipped.
|
||||
bool fFlipY = false;
|
||||
// If true the destination fragment color is read sk_FragColor. It must be declared inout.
|
||||
bool fFragColorIsInOut = false;
|
||||
// if true, Setting objects (e.g. sk_Caps.fbFetchSupport) should be replaced with their
|
||||
// constant equivalents during compilation
|
||||
bool fReplaceSettings = true;
|
||||
// if true, all halfs are forced to be floats
|
||||
bool fForceHighPrecision = false;
|
||||
// if true, add -0.5 bias to LOD of all texture lookups
|
||||
bool fSharpenTextures = false;
|
||||
// if the program needs to create an RTHeight uniform, this is its offset in the uniform
|
||||
// buffer
|
||||
int fRTHeightOffset = -1;
|
||||
// if the program needs to create an RTHeight uniform and is creating spriv, this is the
|
||||
// binding and set number of the uniform buffer.
|
||||
int fRTHeightBinding = -1;
|
||||
int fRTHeightSet = -1;
|
||||
// If layout(set=S, binding=B) is not specified for a uniform, these values will be used.
|
||||
// At present, zero is always used by our backends.
|
||||
int fDefaultUniformSet = 0;
|
||||
int fDefaultUniformBinding = 0;
|
||||
// If true, remove any uncalled functions other than main(). Note that a function which
|
||||
// starts out being used may end up being uncalled after optimization.
|
||||
bool fRemoveDeadFunctions = true;
|
||||
// Sets an upper limit on the acceptable amount of code growth from inlining.
|
||||
// A value of zero will disable the inliner entirely.
|
||||
int fInlineThreshold = SkSL::kDefaultInlineThreshold;
|
||||
// true to enable optimization passes
|
||||
bool fOptimize = true;
|
||||
// If true, implicit conversions to lower precision numeric types are allowed
|
||||
// (eg, float to half)
|
||||
bool fAllowNarrowingConversions = false;
|
||||
// If true, then Debug code will run SPIR-V output through the validator to ensure its
|
||||
// correctness
|
||||
bool fValidateSPIRV = true;
|
||||
// If true, any synthetic uniforms must use push constant syntax
|
||||
bool fUsePushConstants = false;
|
||||
// Permits static if/switch statements to be used with non-constant tests. This is used when
|
||||
// producing H and CPP code; the static tests don't have to have constant values *yet*, but
|
||||
// the generated code will contain a static test which then does have to be a constant.
|
||||
bool fPermitInvalidStaticTests = false;
|
||||
};
|
||||
using Settings = ProgramSettings;
|
||||
|
||||
struct Inputs {
|
||||
// if true, this program requires the render target width uniform to be defined
|
||||
@ -179,16 +147,7 @@ struct Program {
|
||||
}
|
||||
};
|
||||
|
||||
enum Kind {
|
||||
kFragment_Kind,
|
||||
kVertex_Kind,
|
||||
kGeometry_Kind,
|
||||
kFragmentProcessor_Kind,
|
||||
kRuntimeEffect_Kind,
|
||||
kGeneric_Kind,
|
||||
};
|
||||
|
||||
Program(Kind kind,
|
||||
Program(ProgramKind kind,
|
||||
std::unique_ptr<String> source,
|
||||
Settings settings,
|
||||
const ShaderCapsClass* caps,
|
||||
@ -298,7 +257,7 @@ struct Program {
|
||||
// The iterator's value type is 'std::unique_ptr<ProgramElement>', and mutation is allowed.
|
||||
const std::vector<std::unique_ptr<ProgramElement>>& ownedElements() const { return fElements; }
|
||||
|
||||
Kind fKind;
|
||||
ProgramKind fKind;
|
||||
std::unique_ptr<String> fSource;
|
||||
Settings fSettings;
|
||||
const ShaderCapsClass* fCaps;
|
||||
|
@ -16,7 +16,7 @@ static void test(skiatest::Reporter* r, const GrShaderCaps& caps, const char* sr
|
||||
SkSL::Compiler compiler(&caps);
|
||||
SkSL::StringStream output;
|
||||
std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
|
||||
SkSL::Program::kFragmentProcessor_Kind,
|
||||
SkSL::ProgramKind::kFragmentProcessor,
|
||||
SkSL::String(src),
|
||||
settings);
|
||||
if (!program) {
|
||||
|
@ -12,7 +12,7 @@
|
||||
static void test(skiatest::Reporter* r,
|
||||
const GrShaderCaps& caps,
|
||||
const char* src,
|
||||
SkSL::Program::Kind kind = SkSL::Program::kFragment_Kind) {
|
||||
SkSL::ProgramKind kind = SkSL::ProgramKind::kFragment) {
|
||||
SkSL::Compiler compiler(&caps);
|
||||
SkSL::Program::Settings settings;
|
||||
SkSL::String output;
|
||||
|
@ -23,7 +23,7 @@ struct ProgramBuilder {
|
||||
// For convenience, so we can test functions other than (and not called by) main.
|
||||
settings.fRemoveDeadFunctions = false;
|
||||
|
||||
fProgram = fCompiler.convertProgram(SkSL::Program::kGeneric_Kind, SkSL::String(src),
|
||||
fProgram = fCompiler.convertProgram(SkSL::ProgramKind::kGeneric, SkSL::String(src),
|
||||
settings);
|
||||
if (!fProgram) {
|
||||
ERRORF(r, "Program failed to compile:\n%s\n%s\n", src, fCompiler.errorText().c_str());
|
||||
@ -626,7 +626,7 @@ static void expect_failure(skiatest::Reporter* r, const char* src) {
|
||||
GrShaderCaps caps(GrContextOptions{});
|
||||
SkSL::Compiler compiler(&caps);
|
||||
SkSL::Program::Settings settings;
|
||||
auto program = compiler.convertProgram(SkSL::Program::kGeneric_Kind,
|
||||
auto program = compiler.convertProgram(SkSL::ProgramKind::kGeneric,
|
||||
SkSL::String(src), settings);
|
||||
REPORTER_ASSERT(r, !program);
|
||||
}
|
||||
@ -906,7 +906,7 @@ DEF_TEST(SkSLInterpreterExternalFunction, r) {
|
||||
std::vector<std::unique_ptr<SkSL::ExternalFunction>> externalFunctions;
|
||||
externalFunctions.push_back(std::make_unique<ExternalSqrt>("external", compiler));
|
||||
std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
|
||||
SkSL::Program::kGeneric_Kind, SkSL::String(src), settings, &externalFunctions);
|
||||
SkSL::ProgramKind::kGeneric, SkSL::String(src), settings, &externalFunctions);
|
||||
REPORTER_ASSERT(r, program);
|
||||
|
||||
const SkSL::FunctionDefinition* main = SkSL::Program_GetFunction(*program, "main");
|
||||
@ -964,7 +964,7 @@ DEF_TEST(SkSLInterpreterExternalTable, r) {
|
||||
|
||||
externalFunctions.push_back(std::make_unique<ExternalTable>("table", compiler, &u));
|
||||
std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
|
||||
SkSL::Program::kGeneric_Kind, SkSL::String(src), settings, &externalFunctions);
|
||||
SkSL::ProgramKind::kGeneric, SkSL::String(src), settings, &externalFunctions);
|
||||
REPORTER_ASSERT(r, program);
|
||||
|
||||
const SkSL::FunctionDefinition* main = SkSL::Program_GetFunction(*program, "main");
|
||||
|
@ -12,7 +12,7 @@
|
||||
static void test(skiatest::Reporter* r,
|
||||
const GrShaderCaps& caps,
|
||||
const char* src,
|
||||
SkSL::Program::Kind kind = SkSL::Program::kFragment_Kind) {
|
||||
SkSL::ProgramKind kind = SkSL::ProgramKind::kFragment) {
|
||||
SkSL::Compiler compiler(&caps);
|
||||
SkSL::Program::Settings settings;
|
||||
SkSL::String output;
|
||||
|
@ -12,7 +12,7 @@
|
||||
static void test(skiatest::Reporter* r,
|
||||
const GrShaderCaps& caps,
|
||||
const char* src,
|
||||
SkSL::Program::Kind kind = SkSL::Program::kFragment_Kind) {
|
||||
SkSL::ProgramKind kind = SkSL::ProgramKind::kFragment) {
|
||||
SkSL::Compiler compiler(&caps);
|
||||
SkSL::Program::Settings settings;
|
||||
SkSL::String output;
|
||||
|
Loading…
Reference in New Issue
Block a user