Reland image storage with fixes.
Revert "Revert "Initial OpenGL Image support.""
This reverts commit 59dc41175d99d0a31c046aec0c26c4d82a3a3574.
BUG=skia:
Change-Id: Ibe3c87ce7f746f065fdbcc5a518388cc291112f5
Reviewed-on: https://skia-review.googlesource.com/5131
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/glsl/GrGLSL.h b/src/gpu/glsl/GrGLSL.h
index d27b25f..417f6d7 100644
--- a/src/gpu/glsl/GrGLSL.h
+++ b/src/gpu/glsl/GrGLSL.h
@@ -121,6 +121,10 @@
return "texture2D";
case kSampler_GrSLType:
return "sampler";
+ case kImageStorage2D_GrSLType:
+ return "image2D";
+ case kIImageStorage2D_GrSLType:
+ return "iimage2D";
}
SkFAIL("Unknown shader var type.");
return ""; // suppress warning
diff --git a/src/gpu/glsl/GrGLSLCaps.cpp b/src/gpu/glsl/GrGLSLCaps.cpp
index 5bb22b3..57e5a0c 100644
--- a/src/gpu/glsl/GrGLSLCaps.cpp
+++ b/src/gpu/glsl/GrGLSLCaps.cpp
@@ -47,10 +47,10 @@
fMaxGeometrySamplers = 0;
fMaxFragmentSamplers = 0;
fMaxCombinedSamplers = 0;
- fMaxVertexImages = 0;
- fMaxGeometryImages = 0;
- fMaxFragmentImages = 0;
- fMaxCombinedImages = 0;
+ fMaxVertexImageStorages = 0;
+ fMaxGeometryImageStorages = 0;
+ fMaxFragmentImageStorages = 0;
+ fMaxCombinedImageStorages = 0;
fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction;
}
@@ -95,10 +95,10 @@
r.appendf("Max GS Samplers: %d\n", fMaxGeometrySamplers);
r.appendf("Max FS Samplers: %d\n", fMaxFragmentSamplers);
r.appendf("Max Combined Samplers: %d\n", fMaxFragmentSamplers);
- r.appendf("Max VS Images: %d\n", fMaxVertexImages);
- r.appendf("Max GS Images: %d\n", fMaxGeometryImages);
- r.appendf("Max FS Images: %d\n", fMaxFragmentImages);
- r.appendf("Max Combined Images: %d\n", fMaxFragmentImages);
+ r.appendf("Max VS Image Storages: %d\n", fMaxVertexImageStorages);
+ r.appendf("Max GS Image Storages: %d\n", fMaxGeometryImageStorages);
+ r.appendf("Max FS Image Storages: %d\n", fMaxFragmentImageStorages);
+ r.appendf("Max Combined Image Storages: %d\n", fMaxFragmentImageStorages);
r.appendf("Advanced blend equation interaction: %s\n",
kAdvBlendEqInteractionStr[fAdvBlendEqInteraction]);
return r;
diff --git a/src/gpu/glsl/GrGLSLCaps.h b/src/gpu/glsl/GrGLSLCaps.h
index 4c53ad0..11ce754 100644
--- a/src/gpu/glsl/GrGLSLCaps.h
+++ b/src/gpu/glsl/GrGLSLCaps.h
@@ -157,13 +157,13 @@
int maxCombinedSamplers() const { return fMaxCombinedSamplers; }
- int maxVertexImages() const { return fMaxVertexImages; }
+ int maxVertexImageStorages() const { return fMaxVertexImageStorages; }
- int maxGeometryImages() const { return fMaxGeometryImages; }
+ int maxGeometryImageStorages() const { return fMaxGeometryImageStorages; }
- int maxFragmentImages() const { return fMaxFragmentImages; }
+ int maxFragmentImageStorages() const { return fMaxFragmentImageStorages; }
- int maxCombinedImages() const { return fMaxCombinedImages; }
+ int maxCombinedImageStorages() const { return fMaxCombinedImageStorages; }
/**
* Given a texture's config, this determines what swizzle must be appended to accesses to the
@@ -238,10 +238,10 @@
int fMaxFragmentSamplers;
int fMaxCombinedSamplers;
- int fMaxVertexImages;
- int fMaxGeometryImages;
- int fMaxFragmentImages;
- int fMaxCombinedImages;
+ int fMaxVertexImageStorages;
+ int fMaxGeometryImageStorages;
+ int fMaxFragmentImageStorages;
+ int fMaxCombinedImageStorages;
AdvBlendEqInteraction fAdvBlendEqInteraction;
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
index 5ae7fee..8c32482 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
@@ -49,6 +49,7 @@
TransformedCoordVars coordVars = args.fTransformedCoords.childInputs(childIndex);
TextureSamplers textureSamplers = args.fTexSamplers.childInputs(childIndex);
BufferSamplers bufferSamplers = args.fBufferSamplers.childInputs(childIndex);
+ ImageStorages imageStorages = args.fImageStorages.childInputs(childIndex);
EmitArgs childArgs(fragBuilder,
args.fUniformHandler,
args.fGLSLCaps,
@@ -58,6 +59,7 @@
coordVars,
textureSamplers,
bufferSamplers,
+ imageStorages,
args.fGpImplementsDistanceVector);
this->childProcessor(childIndex)->emitCode(childArgs);
fragBuilder->codeAppend("}\n");
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.h b/src/gpu/glsl/GrGLSLFragmentProcessor.h
index aba68b7..c815423 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.h
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.h
@@ -11,13 +11,13 @@
#include "GrFragmentProcessor.h"
#include "GrShaderVar.h"
#include "glsl/GrGLSLProgramDataManager.h"
+#include "glsl/GrGLSLUniformHandler.h"
class GrProcessor;
class GrProcessorKeyBuilder;
class GrGLSLCaps;
class GrGLSLFPBuilder;
class GrGLSLFPFragmentBuilder;
-class GrGLSLUniformHandler;
class GrGLSLFragmentProcessor {
public:
@@ -29,8 +29,9 @@
}
}
- typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
- typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
+ using UniformHandle = GrGLSLUniformHandler::UniformHandle;
+ using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
+ using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
private:
/**
@@ -74,6 +75,8 @@
&GrProcessor::numTextureSamplers>;
using BufferSamplers = BuilderInputProvider<SamplerHandle, GrProcessor,
&GrProcessor::numBuffers>;
+ using ImageStorages = BuilderInputProvider<ImageStorageHandle, GrProcessor,
+ &GrProcessor::numImageStorages>;
/** Called when the program stage should insert its code into the shaders. The code in each
shader will be in its own block ({}) and so locally scoped names will not collide across
@@ -99,6 +102,12 @@
@param bufferSamplers Contains one entry for each BufferAccess of the GrProcessor. These
can be passed to the builder to emit buffer reads in the generated
code.
+ @param imageStorages Contains one entry for each ImageStorageAccess of the GrProcessor.
+ These can be passed to the builder to emit image loads and stores
+ in the generated code.
+ @param gpImplementsDistanceVector
+ Does the GrGeometryProcessor implement the feature where it
+ provides a vector to the nearest edge of the shape being rendered.
*/
struct EmitArgs {
EmitArgs(GrGLSLFPFragmentBuilder* fragBuilder,
@@ -110,6 +119,7 @@
const TransformedCoordVars& transformedCoordVars,
const TextureSamplers& textureSamplers,
const BufferSamplers& bufferSamplers,
+ const ImageStorages& imageStorages,
bool gpImplementsDistanceVector)
: fFragBuilder(fragBuilder)
, fUniformHandler(uniformHandler)
@@ -120,6 +130,7 @@
, fTransformedCoords(transformedCoordVars)
, fTexSamplers(textureSamplers)
, fBufferSamplers(bufferSamplers)
+ , fImageStorages(imageStorages)
, fGpImplementsDistanceVector(gpImplementsDistanceVector) {}
GrGLSLFPFragmentBuilder* fFragBuilder;
GrGLSLUniformHandler* fUniformHandler;
@@ -130,6 +141,7 @@
const TransformedCoordVars& fTransformedCoords;
const TextureSamplers& fTexSamplers;
const BufferSamplers& fBufferSamplers;
+ const ImageStorages& fImageStorages;
bool fGpImplementsDistanceVector;
};
diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
index 1991639..b398cfd 100644
--- a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
+++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
@@ -11,6 +11,7 @@
#include "GrFragmentProcessor.h"
#include "GrPrimitiveProcessor.h"
#include "glsl/GrGLSLProgramDataManager.h"
+#include "glsl/GrGLSLUniformHandler.h"
class GrBatchTracker;
class GrPrimitiveProcessor;
@@ -18,7 +19,6 @@
class GrGLSLPPFragmentBuilder;
class GrGLSLGeometryBuilder;
class GrGLSLGPBuilder;
-class GrGLSLUniformHandler;
class GrGLSLVaryingHandler;
class GrGLSLVertexBuilder;
@@ -28,8 +28,9 @@
virtual ~GrGLSLPrimitiveProcessor() {}
- typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
- typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
+ using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
+ using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
+ using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
/**
* This class provides access to the GrCoordTransforms across all GrFragmentProcessors in a
@@ -77,6 +78,7 @@
const char* distanceVectorName,
const SamplerHandle* texSamplers,
const SamplerHandle* bufferSamplers,
+ const ImageStorageHandle* imageStorages,
FPCoordTransformHandler* transformHandler)
: fVertBuilder(vertBuilder)
, fGeomBuilder(geomBuilder)
@@ -90,6 +92,7 @@
, fDistanceVectorName(distanceVectorName)
, fTexSamplers(texSamplers)
, fBufferSamplers(bufferSamplers)
+ , fImageStorages(imageStorages)
, fFPCoordTransformHandler(transformHandler) {}
GrGLSLVertexBuilder* fVertBuilder;
GrGLSLGeometryBuilder* fGeomBuilder;
@@ -103,6 +106,7 @@
const char* fDistanceVectorName;
const SamplerHandle* fTexSamplers;
const SamplerHandle* fBufferSamplers;
+ const ImageStorageHandle* fImageStorages;
FPCoordTransformHandler* fFPCoordTransformHandler;
};
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index e8097c7..0c1661d 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -31,7 +31,10 @@
, fXferProcessor(nullptr)
, fNumVertexSamplers(0)
, fNumGeometrySamplers(0)
- , fNumFragmentSamplers(0) {
+ , fNumFragmentSamplers(0)
+ , fNumVertexImageStorages(0)
+ , fNumGeometryImageStorages(0)
+ , fNumFragmentImageStorages(0) {
}
void GrGLSLProgramBuilder::addFeature(GrShaderFlags shaders,
@@ -66,7 +69,7 @@
this->emitFSOutputSwizzle(this->pipeline().getXferProcessor().hasSecondaryOutput());
}
- return this->checkSamplerCounts();
+ return this->checkSamplerCounts() && this->checkImageStorageCounts();
}
void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& proc,
@@ -97,9 +100,10 @@
SkASSERT(!fGeometryProcessor);
fGeometryProcessor = proc.createGLSLInstance(*this->glslCaps());
- SkSTArray<4, SamplerHandle> texSamplers(proc.numTextureSamplers());
- SkSTArray<2, SamplerHandle> bufferSamplers(proc.numBuffers());
- this->emitSamplers(proc, &texSamplers, &bufferSamplers);
+ SkSTArray<4, SamplerHandle> texSamplers(proc.numTextureSamplers());
+ SkSTArray<2, SamplerHandle> bufferSamplers(proc.numBuffers());
+ SkSTArray<2, ImageStorageHandle> imageStorages(proc.numImageStorages());
+ this->emitSamplersAndImageStorages(proc, &texSamplers, &bufferSamplers, &imageStorages);
GrGLSLPrimitiveProcessor::FPCoordTransformHandler transformHandler(fPipeline,
&fTransformedCoordVars);
@@ -115,6 +119,7 @@
distanceVectorName,
texSamplers.begin(),
bufferSamplers.begin(),
+ imageStorages.begin(),
&transformHandler);
fGeometryProcessor->emitCode(args);
@@ -163,15 +168,18 @@
SkSTArray<4, SamplerHandle> textureSamplerArray(fp.numTextureSamplers());
SkSTArray<2, SamplerHandle> bufferSamplerArray(fp.numBuffers());
+ SkSTArray<2, ImageStorageHandle> imageStorageArray(fp.numImageStorages());
GrFragmentProcessor::Iter iter(&fp);
while (const GrFragmentProcessor* subFP = iter.next()) {
- this->emitSamplers(*subFP, &textureSamplerArray, &bufferSamplerArray);
+ this->emitSamplersAndImageStorages(*subFP, &textureSamplerArray, &bufferSamplerArray,
+ &imageStorageArray);
}
const GrShaderVar* coordVars = fTransformedCoordVars.begin() + transformedCoordVarsIdx;
GrGLSLFragmentProcessor::TransformedCoordVars coords(&fp, coordVars);
GrGLSLFragmentProcessor::TextureSamplers textureSamplers(&fp, textureSamplerArray.begin());
GrGLSLFragmentProcessor::BufferSamplers bufferSamplers(&fp, bufferSamplerArray.begin());
+ GrGLSLFragmentProcessor::ImageStorages imageStorages(&fp, imageStorageArray.begin());
GrGLSLFragmentProcessor::EmitArgs args(&fFS,
this->uniformHandler(),
this->glslCaps(),
@@ -181,6 +189,7 @@
coords,
textureSamplers,
bufferSamplers,
+ imageStorages,
this->primitiveProcessor().implementsDistanceVector());
fragProc->emitCode(args);
@@ -217,9 +226,10 @@
openBrace.printf("{ // Xfer Processor: %s\n", xp.name());
fFS.codeAppend(openBrace.c_str());
- SkSTArray<4, SamplerHandle> texSamplers(xp.numTextureSamplers());
- SkSTArray<2, SamplerHandle> bufferSamplers(xp.numBuffers());
- this->emitSamplers(xp, &texSamplers, &bufferSamplers);
+ SkSTArray<4, SamplerHandle> texSamplers(xp.numTextureSamplers());
+ SkSTArray<2, SamplerHandle> bufferSamplers(xp.numBuffers());
+ SkSTArray<2, ImageStorageHandle> imageStorageArray(xp.numImageStorages());
+ this->emitSamplersAndImageStorages(xp, &texSamplers, &bufferSamplers, &imageStorageArray);
bool usePLSDstRead = (plsState == GrPixelLocalStorageState::kFinish_GrPixelLocalStorageState);
GrGLSLXferProcessor::EmitArgs args(&fFS,
@@ -231,6 +241,7 @@
fFS.getSecondaryColorOutputName(),
texSamplers.begin(),
bufferSamplers.begin(),
+ imageStorageArray.begin(),
usePLSDstRead);
fXferProcessor->emitCode(args);
@@ -240,13 +251,16 @@
fFS.codeAppend("}");
}
-void GrGLSLProgramBuilder::emitSamplers(const GrProcessor& processor,
- SkTArray<SamplerHandle>* outTexSamplers,
- SkTArray<SamplerHandle>* outBufferSamplers) {
+void GrGLSLProgramBuilder::emitSamplersAndImageStorages(
+ const GrProcessor& processor,
+ SkTArray<SamplerHandle>* outTexSamplerHandles,
+ SkTArray<SamplerHandle>* outBufferSamplerHandles,
+ SkTArray<ImageStorageHandle>* outImageStorageHandles) {
SkString name;
int numTextureSamplers = processor.numTextureSamplers();
for (int t = 0; t < numTextureSamplers; ++t) {
const GrProcessor::TextureSampler& sampler = processor.textureSampler(t);
+ name.printf("TextureSampler_%d", outTexSamplerHandles->count());
GrSLType samplerType = sampler.texture()->texturePriv().samplerType();
if (kTextureExternalSampler_GrSLType == samplerType) {
const char* externalFeatureString = this->glslCaps()->externalTextureExtensionString();
@@ -256,9 +270,9 @@
1 << GrGLSLShaderBuilder::kExternalTexture_GLSLPrivateFeature,
externalFeatureString);
}
- name.printf("TextureSampler_%d", outTexSamplers->count());
- this->emitSampler(samplerType, sampler.texture()->config(),
- name.c_str(), sampler.visibility(), outTexSamplers);
+ this->emitSampler(samplerType, sampler.texture()->config(), name.c_str(),
+ sampler.visibility(), outTexSamplerHandles);
+
}
if (int numBuffers = processor.numBuffers()) {
@@ -267,9 +281,9 @@
for (int b = 0; b < numBuffers; ++b) {
const GrProcessor::BufferAccess& access = processor.bufferAccess(b);
- name.printf("BufferSampler_%d", outBufferSamplers->count());
+ name.printf("BufferSampler_%d", outBufferSamplerHandles->count());
this->emitSampler(kBufferSampler_GrSLType, access.texelConfig(), name.c_str(),
- access.visibility(), outBufferSamplers);
+ access.visibility(), outBufferSamplerHandles);
texelBufferVisibility |= access.visibility();
}
@@ -279,13 +293,19 @@
extension);
}
}
+ int numImageStorages = processor.numImageStorages();
+ for (int i = 0; i < numImageStorages; ++i) {
+ const GrProcessor::ImageStorageAccess& imageStorageAccess = processor.imageStorageAccess(i);
+ name.printf("Image_%d", outImageStorageHandles->count());
+ this->emitImageStorage(imageStorageAccess, name.c_str(), outImageStorageHandles);
+ }
}
void GrGLSLProgramBuilder::emitSampler(GrSLType samplerType,
GrPixelConfig config,
const char* name,
GrShaderFlags visibility,
- SkTArray<SamplerHandle>* outSamplers) {
+ SkTArray<SamplerHandle>* outSamplerHandles) {
if (visibility & kVertex_GrShaderFlag) {
++fNumVertexSamplers;
}
@@ -298,12 +318,31 @@
}
GrSLPrecision precision = this->glslCaps()->samplerPrecision(config, visibility);
GrSwizzle swizzle = this->glslCaps()->configTextureSwizzle(config);
- SamplerHandle handle = this->uniformHandler()->addSampler(visibility,
- swizzle,
- samplerType,
- precision,
- name);
- outSamplers->emplace_back(handle);
+ outSamplerHandles->emplace_back(this->uniformHandler()->addSampler(visibility,
+ swizzle,
+ samplerType,
+ precision,
+ name));
+}
+
+void GrGLSLProgramBuilder::emitImageStorage(const GrProcessor::ImageStorageAccess& access,
+ const char* name,
+ SkTArray<ImageStorageHandle>* outImageStorageHandles) {
+ if (access.visibility() & kVertex_GrShaderFlag) {
+ ++fNumVertexImageStorages;
+ }
+ if (access.visibility() & kGeometry_GrShaderFlag) {
+ SkASSERT(this->primitiveProcessor().willUseGeoShader());
+ ++fNumGeometryImageStorages;
+ }
+ if (access.visibility() & kFragment_GrShaderFlag) {
+ ++fNumFragmentImageStorages;
+ }
+ GrSLType uniformType = access.texture()->texturePriv().imageStorageType();
+ ImageStorageHandle handle = this->uniformHandler()->addImageStorage(access.visibility(),
+ uniformType, access.format(), access.memoryModel(), access.restrict(), access.ioType(),
+ name);
+ outImageStorageHandles->emplace_back(handle);
}
void GrGLSLProgramBuilder::emitFSOutputSwizzle(bool hasSecondaryOutput) {
@@ -345,6 +384,30 @@
return true;
}
+bool GrGLSLProgramBuilder::checkImageStorageCounts() {
+ const GrGLSLCaps& glslCaps = *this->glslCaps();
+ if (fNumVertexImageStorages > glslCaps.maxVertexImageStorages()) {
+ GrCapsDebugf(this->caps(), "Program would use too many vertex images\n");
+ return false;
+ }
+ if (fNumGeometryImageStorages > glslCaps.maxGeometryImageStorages()) {
+ GrCapsDebugf(this->caps(), "Program would use too many geometry images\n");
+ return false;
+ }
+ if (fNumFragmentImageStorages > glslCaps.maxFragmentImageStorages()) {
+ GrCapsDebugf(this->caps(), "Program would use too many fragment images\n");
+ return false;
+ }
+ // If the same image is used in two different shaders, it counts as two combined images.
+ int numCombinedImages = fNumVertexImageStorages + fNumGeometryImageStorages +
+ fNumFragmentImageStorages;
+ if (numCombinedImages > glslCaps.maxCombinedImageStorages()) {
+ GrCapsDebugf(this->caps(), "Program would use too many combined images\n");
+ return false;
+ }
+ return true;
+}
+
#ifdef SK_DEBUG
void GrGLSLProgramBuilder::verify(const GrPrimitiveProcessor& gp) {
SkASSERT(fFS.usedProcessorFeatures() == gp.requiredFeatures());
@@ -393,7 +456,6 @@
this->uniformHandler()->appendUniformDecls(visibility, out);
}
-
void GrGLSLProgramBuilder::addRTAdjustmentUniform(GrSLPrecision precision,
const char* name,
const char** outName) {
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.h b/src/gpu/glsl/GrGLSLProgramBuilder.h
index 6c1eb3b..5543537 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.h
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.h
@@ -28,7 +28,9 @@
class GrGLSLProgramBuilder {
public:
- typedef GrGLSLUniformHandler::UniformHandle UniformHandle;
+ using UniformHandle = GrGLSLUniformHandler::UniformHandle;
+ using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
+ using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
virtual ~GrGLSLProgramBuilder() {}
@@ -42,8 +44,6 @@
void appendUniformDecls(GrShaderFlags visibility, SkString*) const;
- typedef GrGLSLUniformHandler::SamplerHandle SamplerHandle;
-
const GrShaderVar& samplerVariable(SamplerHandle handle) const {
return this->uniformHandler()->samplerVariable(handle);
}
@@ -52,6 +52,10 @@
return this->uniformHandler()->samplerSwizzle(handle);
}
+ const GrShaderVar& imageStorageVariable(ImageStorageHandle handle) const {
+ return this->uniformHandler()->imageStorageVariable(handle);
+ }
+
// Handles for program uniforms (other than per-effect uniforms)
struct BuiltinUniformHandles {
UniformHandle fRTAdjustmentUni;
@@ -156,17 +160,18 @@
const GrGLSLExpr4& coverageIn,
bool ignoresCoverage,
GrPixelLocalStorageState plsState);
-
- void emitSamplers(const GrProcessor& processor,
- SkTArray<SamplerHandle>* outTexSamplers,
- SkTArray<SamplerHandle>* outBufferSamplers);
- void emitSampler(GrSLType samplerType,
- GrPixelConfig,
- const char* name,
- GrShaderFlags visibility,
- SkTArray<SamplerHandle>* outSamplers);
+ void emitSamplersAndImageStorages(const GrProcessor& processor,
+ SkTArray<SamplerHandle>* outTexSamplerHandles,
+ SkTArray<SamplerHandle>* outBufferSamplerHandles,
+ SkTArray<ImageStorageHandle>* outImageStorageHandles);
+ void emitSampler(GrSLType samplerType, GrPixelConfig, const char* name,
+ GrShaderFlags visibility, SkTArray<SamplerHandle >* outSamplerHandles);
+ void emitImageStorage(const GrProcessor::ImageStorageAccess&,
+ const char* name,
+ SkTArray<ImageStorageHandle>* outImageStorageHandles);
void emitFSOutputSwizzle(bool hasSecondaryOutput);
bool checkSamplerCounts();
+ bool checkImageStorageCounts();
#ifdef SK_DEBUG
void verify(const GrPrimitiveProcessor&);
@@ -177,6 +182,9 @@
int fNumVertexSamplers;
int fNumGeometrySamplers;
int fNumFragmentSamplers;
+ int fNumVertexImageStorages;
+ int fNumGeometryImageStorages;
+ int fNumFragmentImageStorages;
SkSTArray<4, GrShaderVar> fTransformedCoordVars;
};
diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.cpp b/src/gpu/glsl/GrGLSLShaderBuilder.cpp
index b6e7ce9..79e977c 100644
--- a/src/gpu/glsl/GrGLSLShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLShaderBuilder.cpp
@@ -162,6 +162,16 @@
this->appendTexelFetch(&this->code(), samplerHandle, coordExpr);
}
+void GrGLSLShaderBuilder::appendImageStorageLoad(SkString* out, ImageStorageHandle handle,
+ const char* coordExpr) {
+ const GrShaderVar& imageStorage = fProgramBuilder->imageStorageVariable(handle);
+ out->appendf("imageLoad(%s, %s)", imageStorage.c_str(), coordExpr);
+}
+
+void GrGLSLShaderBuilder::appendImageStorageLoad(ImageStorageHandle handle, const char* coordExpr) {
+ this->appendImageStorageLoad(&this->code(), handle, coordExpr);
+}
+
bool GrGLSLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionName) {
if (featureBit & fFeaturesAddedMask) {
return false;
diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.h b/src/gpu/glsl/GrGLSLShaderBuilder.h
index b568369..983d50b 100644
--- a/src/gpu/glsl/GrGLSLShaderBuilder.h
+++ b/src/gpu/glsl/GrGLSLShaderBuilder.h
@@ -25,7 +25,8 @@
GrGLSLShaderBuilder(GrGLSLProgramBuilder* program);
virtual ~GrGLSLShaderBuilder() {}
- typedef GrGLSLUniformHandler::SamplerHandle SamplerHandle;
+ using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
+ using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
/** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
@@ -72,6 +73,11 @@
/** Version of above that appends the result to the shader code instead.*/
void appendTexelFetch(SamplerHandle, const char* coordExpr);
+ /** Creates a string of shader code that performs an image load. */
+ void appendImageStorageLoad(SkString* out, ImageStorageHandle, const char* coordExpr);
+ /** Version of above that appends the result to the shader code instead. */
+ void appendImageStorageLoad(ImageStorageHandle, const char* coordExpr);
+
/**
* Adds a constant declaration to the top of the shader.
*/
diff --git a/src/gpu/glsl/GrGLSLUniformHandler.h b/src/gpu/glsl/GrGLSLUniformHandler.h
index d49fbd4..3d21c1c 100644
--- a/src/gpu/glsl/GrGLSLUniformHandler.h
+++ b/src/gpu/glsl/GrGLSLUniformHandler.h
@@ -18,8 +18,9 @@
public:
virtual ~GrGLSLUniformHandler() {}
- typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
- typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
+ using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
+ GR_DEFINE_RESOURCE_HANDLE_CLASS(SamplerHandle);
+ GR_DEFINE_RESOURCE_HANDLE_CLASS(ImageStorageHandle);
/** Add a uniform variable to the current program, that has visibility in one or more shaders.
visibility is a bitfield of GrShaderFlag values indicating from which shaders the uniform
@@ -67,6 +68,11 @@
virtual SamplerHandle addSampler(uint32_t visibility, GrSwizzle, GrSLType, GrSLPrecision,
const char* name) = 0;
+ virtual const GrShaderVar& imageStorageVariable(ImageStorageHandle) const = 0;
+ virtual ImageStorageHandle addImageStorage(uint32_t visibility, GrSLType type,
+ GrImageStorageFormat, GrSLMemoryModel, GrSLRestrict,
+ GrIOType, const char* name) = 0;
+
virtual UniformHandle internalAddUniformArray(uint32_t visibility,
GrSLType type,
GrSLPrecision precision,
diff --git a/src/gpu/glsl/GrGLSLXferProcessor.h b/src/gpu/glsl/GrGLSLXferProcessor.h
index bf6ee64..69e0072 100644
--- a/src/gpu/glsl/GrGLSLXferProcessor.h
+++ b/src/gpu/glsl/GrGLSLXferProcessor.h
@@ -9,10 +9,10 @@
#define GrGLSLXferProcessor_DEFINED
#include "glsl/GrGLSLProgramDataManager.h"
+#include "glsl/GrGLSLUniformHandler.h"
class GrXferProcessor;
class GrGLSLCaps;
-class GrGLSLUniformHandler;
class GrGLSLXPBuilder;
class GrGLSLXPFragmentBuilder;
@@ -21,7 +21,8 @@
GrGLSLXferProcessor() {}
virtual ~GrGLSLXferProcessor() {}
- typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
+ using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
+ using ImageStorageHandle = GrGLSLUniformHandler::ImageStorageHandle;
struct EmitArgs {
EmitArgs(GrGLSLXPFragmentBuilder* fragBuilder,
@@ -34,6 +35,7 @@
const char* outputSecondary,
const SamplerHandle* texSamplers,
const SamplerHandle* bufferSamplers,
+ const ImageStorageHandle* imageStorages,
const bool usePLSDstRead)
: fXPFragBuilder(fragBuilder)
, fUniformHandler(uniformHandler)
@@ -45,6 +47,7 @@
, fOutputSecondary(outputSecondary)
, fTexSamplers(texSamplers)
, fBufferSamplers(bufferSamplers)
+ , fImageStorages(imageStorages)
, fUsePLSDstRead(usePLSDstRead) {}
GrGLSLXPFragmentBuilder* fXPFragBuilder;
@@ -57,6 +60,7 @@
const char* fOutputSecondary;
const SamplerHandle* fTexSamplers;
const SamplerHandle* fBufferSamplers;
+ const ImageStorageHandle* fImageStorages;
bool fUsePLSDstRead;
};
/**