| Index: src/gpu/glsl/GrGLSLProgramBuilder.cpp
|
| diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
|
| index ccb078b1449c13970c1709317031f3a3556cbdb1..88ef5b92450db92c6b981256e976d06f378f0427 100644
|
| --- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
|
| +++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
|
| @@ -98,7 +98,8 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
|
| fGeometryProcessor = proc.createGLSLInstance(*this->glslCaps());
|
|
|
| SkSTArray<4, GrGLSLSampler> texSamplers(proc.numTextures());
|
| - this->emitSamplers(proc, &texSamplers);
|
| + SkSTArray<2, GrGLSLSampler> bufferSamplers(proc.numBuffers());
|
| + this->emitSamplers(proc, &texSamplers, &bufferSamplers);
|
|
|
| GrGLSLGeometryProcessor::EmitArgs args(&fVS,
|
| &fFS,
|
| @@ -109,6 +110,7 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
|
| outputColor->c_str(),
|
| outputCoverage->c_str(),
|
| texSamplers,
|
| + bufferSamplers,
|
| fCoordTransforms,
|
| &fOutCoords);
|
| fGeometryProcessor->emitCode(args);
|
| @@ -149,7 +151,8 @@ void GrGLSLProgramBuilder::emitAndInstallFragProc(const GrFragmentProcessor& fp,
|
| GrGLSLFragmentProcessor* fragProc = fp.createGLSLInstance();
|
|
|
| SkSTArray<4, GrGLSLSampler> texSamplers(fp.numTextures());
|
| - this->emitSamplers(fp, &texSamplers);
|
| + SkSTArray<2, GrGLSLSampler> bufferSamplers(fp.numBuffers());
|
| + this->emitSamplers(fp, &texSamplers, &bufferSamplers);
|
|
|
| GrGLSLFragmentProcessor::EmitArgs args(&fFS,
|
| this->uniformHandler(),
|
| @@ -158,7 +161,8 @@ void GrGLSLProgramBuilder::emitAndInstallFragProc(const GrFragmentProcessor& fp,
|
| output->c_str(),
|
| input.isOnes() ? nullptr : input.c_str(),
|
| fOutCoords[index],
|
| - texSamplers);
|
| + texSamplers,
|
| + bufferSamplers);
|
| fragProc->emitCode(args);
|
|
|
| // We have to check that effects and the code they emit are consistent, ie if an effect
|
| @@ -194,7 +198,8 @@ void GrGLSLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp,
|
| fFS.codeAppend(openBrace.c_str());
|
|
|
| SkSTArray<4, GrGLSLSampler> texSamplers(xp.numTextures());
|
| - this->emitSamplers(xp, &texSamplers);
|
| + SkSTArray<2, GrGLSLSampler> bufferSamplers(xp.numBuffers());
|
| + this->emitSamplers(xp, &texSamplers, &bufferSamplers);
|
|
|
| bool usePLSDstRead = (plsState == GrPixelLocalStorageState::kFinish_GrPixelLocalStorageState);
|
| GrGLSLXferProcessor::EmitArgs args(&fFS,
|
| @@ -205,6 +210,7 @@ void GrGLSLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp,
|
| fFS.getPrimaryColorOutputName(),
|
| fFS.getSecondaryColorOutputName(),
|
| texSamplers,
|
| + bufferSamplers,
|
| usePLSDstRead);
|
| fXferProcessor->emitCode(args);
|
|
|
| @@ -215,41 +221,65 @@ void GrGLSLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp,
|
| }
|
|
|
| void GrGLSLProgramBuilder::emitSamplers(const GrProcessor& processor,
|
| - GrGLSLSampler::SamplerArray* outTexSamplers) {
|
| - int numTextures = processor.numTextures();
|
| - UniformHandle* localSamplerUniforms = fSamplerUniforms.push_back_n(numTextures);
|
| + GrGLSLSampler::SamplerArray* outTexSamplers,
|
| + GrGLSLSampler::SamplerArray* outBufferSamplers) {
|
| SkString name;
|
| + int numTextures = processor.numTextures();
|
| for (int t = 0; t < numTextures; ++t) {
|
| const GrTextureAccess& access = processor.textureAccess(t);
|
| - GrShaderFlags visibility = access.getVisibility();
|
| - if (visibility & kVertex_GrShaderFlag) {
|
| - ++fNumVertexSamplers;
|
| - }
|
| - if (visibility & kGeometry_GrShaderFlag) {
|
| - SkASSERT(this->primitiveProcessor().willUseGeoShader());
|
| - ++fNumGeometrySamplers;
|
| - }
|
| - if (visibility & kFragment_GrShaderFlag) {
|
| - ++fNumFragmentSamplers;
|
| - }
|
| GrSLType samplerType = access.getTexture()->samplerType();
|
| if (kSamplerExternal_GrSLType == samplerType) {
|
| const char* externalFeatureString = this->glslCaps()->externalTextureExtensionString();
|
| // We shouldn't ever create a GrGLTexture that requires external sampler type
|
| SkASSERT(externalFeatureString);
|
| - this->addFeature(visibility,
|
| + this->addFeature(access.getVisibility(),
|
| 1 << GrGLSLShaderBuilder::kExternalTexture_GLSLPrivateFeature,
|
| externalFeatureString);
|
| }
|
| - GrSLPrecision precision = this->glslCaps()->samplerPrecision(access.getTexture()->config(),
|
| - visibility);
|
| - name.printf("Sampler%d", t);
|
| - localSamplerUniforms[t] = this->uniformHandler()->addUniform(visibility,
|
| - samplerType,
|
| - precision,
|
| - name.c_str());
|
| - outTexSamplers->emplace_back(localSamplerUniforms[t], access.getTexture()->config());
|
| + name.printf("TextureSampler%d", t);
|
| + this->emitSampler(samplerType, access.getTexture()->config(),
|
| + name.c_str(), access.getVisibility(), outTexSamplers);
|
| + }
|
| +
|
| + if (int numBuffers = processor.numBuffers()) {
|
| + SkASSERT(this->glslCaps()->texelBufferSupport());
|
| + GrShaderFlags texelBufferVisibility = kNone_GrShaderFlags;
|
| +
|
| + for (int b = 0; b < numBuffers; ++b) {
|
| + const GrBufferAccess& access = processor.bufferAccess(b);
|
| + name.printf("BufferSampler%d", b);
|
| + this->emitSampler(kSamplerBuffer_GrSLType, access.texelConfig(), name.c_str(),
|
| + access.visibility(), outBufferSamplers);
|
| + texelBufferVisibility |= access.visibility();
|
| + }
|
| +
|
| + if (const char* extension = this->glslCaps()->texelBufferExtensionString()) {
|
| + this->addFeature(texelBufferVisibility,
|
| + 1 << GrGLSLShaderBuilder::kTexelBuffer_GLSLPrivateFeature,
|
| + extension);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void GrGLSLProgramBuilder::emitSampler(GrSLType samplerType,
|
| + GrPixelConfig config,
|
| + const char* name,
|
| + GrShaderFlags visibility,
|
| + GrGLSLSampler::SamplerArray* outSamplers) {
|
| + if (visibility & kVertex_GrShaderFlag) {
|
| + ++fNumVertexSamplers;
|
| + }
|
| + if (visibility & kGeometry_GrShaderFlag) {
|
| + SkASSERT(this->primitiveProcessor().willUseGeoShader());
|
| + ++fNumGeometrySamplers;
|
| + }
|
| + if (visibility & kFragment_GrShaderFlag) {
|
| + ++fNumFragmentSamplers;
|
| }
|
| + GrSLPrecision precision = this->glslCaps()->samplerPrecision(config, visibility);
|
| + UniformHandle u = this->uniformHandler()->addUniform(visibility, samplerType, precision, name);
|
| + fSamplerUniforms.push_back(u);
|
| + outSamplers->emplace_back(u, config);
|
| }
|
|
|
| void GrGLSLProgramBuilder::emitFSOutputSwizzle(bool hasSecondaryOutput) {
|
|
|