aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2016-11-29 11:59:17 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-11-29 17:42:53 +0000
commitf9f451213a3951d8a61568998de2ddbd643f6693 (patch)
treeba11ab458cbe8c654337bc704c52f4ca73f6b44a /src/gpu/gl
parente18c97b73a0392b2eee57a111122dd5b637e36e6 (diff)
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>
Diffstat (limited to 'src/gpu/gl')
-rw-r--r--src/gpu/gl/GrGLCaps.cpp49
-rw-r--r--src/gpu/gl/GrGLCaps.h11
-rw-r--r--src/gpu/gl/GrGLGpu.cpp26
-rw-r--r--src/gpu/gl/GrGLGpu.h8
-rw-r--r--src/gpu/gl/GrGLProgram.cpp7
-rw-r--r--src/gpu/gl/GrGLProgram.h7
-rw-r--r--src/gpu/gl/GrGLProgramDataManager.cpp10
-rw-r--r--src/gpu/gl/GrGLProgramDataManager.h1
-rw-r--r--src/gpu/gl/GrGLUniformHandler.cpp61
-rw-r--r--src/gpu/gl/GrGLUniformHandler.h12
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.cpp1
11 files changed, 169 insertions, 24 deletions
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 3e9f82a79c..c4f7560be4 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -324,16 +324,29 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
static constexpr int kMaxSaneImages = 4;
GrGLint maxUnits;
GR_GL_GetIntegerv(gli, GR_GL_MAX_IMAGE_UNITS, &maxUnits);
- GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_IMAGE_UNIFORMS, &glslCaps->fMaxVertexImages);
- GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_IMAGE_UNIFORMS, &glslCaps->fMaxGeometryImages);
- GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_IMAGE_UNIFORMS, &glslCaps->fMaxFragmentImages);
- GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_IMAGE_UNIFORMS, &glslCaps->fMaxCombinedImages);
+ GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_IMAGE_UNIFORMS,
+ &glslCaps->fMaxVertexImageStorages);
+ if (glslCaps->fGeometryShaderSupport) {
+ GR_GL_GetIntegerv(gli, GR_GL_MAX_GEOMETRY_IMAGE_UNIFORMS,
+ &glslCaps->fMaxGeometryImageStorages);
+ }
+ GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_IMAGE_UNIFORMS,
+ &glslCaps->fMaxFragmentImageStorages);
+ GR_GL_GetIntegerv(gli, GR_GL_MAX_COMBINED_IMAGE_UNIFORMS,
+ &glslCaps->fMaxCombinedImageStorages);
// We use one unit for every image uniform
- glslCaps->fMaxCombinedImages = SkTMin(SkTMin(glslCaps->fMaxCombinedImages, maxUnits),
- kMaxSaneImages);
- glslCaps->fMaxVertexImages = SkTMin(maxUnits, glslCaps->fMaxVertexImages);
- glslCaps->fMaxGeometryImages = SkTMin(maxUnits, glslCaps->fMaxGeometryImages);
- glslCaps->fMaxFragmentImages = SkTMin(maxUnits, glslCaps->fMaxFragmentImages);
+ glslCaps->fMaxCombinedImageStorages = SkTMin(SkTMin(glslCaps->fMaxCombinedImageStorages,
+ maxUnits), kMaxSaneImages);
+ glslCaps->fMaxVertexImageStorages = SkTMin(maxUnits, glslCaps->fMaxVertexImageStorages);
+ glslCaps->fMaxGeometryImageStorages = SkTMin(maxUnits, glslCaps->fMaxGeometryImageStorages);
+ glslCaps->fMaxFragmentImageStorages = SkTMin(maxUnits,
+ glslCaps->fMaxFragmentImageStorages);
+ // HACK: Currently we only use images in a unit test in the fragment shader. The individual
+ // stage image limits aren't exposed through GrShaderCaps. Soon GrShaderCaps and GrGLSLCaps
+ // will merge and the test can look for fragment support.
+ if (!glslCaps->fMaxFragmentImageStorages) {
+ glslCaps->fImageLoadStoreSupport = false;
+ }
}
/**************************************************************************
@@ -2023,6 +2036,24 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
}
}
+ // We currently only support images on rgba textures formats. We could add additional formats
+ // if desired. The shader builder would have to be updated to add swizzles where appropriate
+ // (e.g. where we use GL_RED textures to implement alpha configs).
+ if (this->shaderCaps()->imageLoadStoreSupport()) {
+ fConfigTable[kRGBA_8888_sint_GrPixelConfig].fFlags |=
+ ConfigInfo::kCanUseAsImageStorage_Flag;
+ // In OpenGL ES a texture may only be used with BindImageTexture if it has been made
+ // immutable via TexStorage. We create non-integer textures as mutable textures using
+ // TexImage because we may lazily add MIP levels. Thus, on ES we currently disable image
+ // storage support for non-integer textures.
+ if (kGL_GrGLStandard == ctxInfo.standard()) {
+ fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseAsImageStorage_Flag;
+ fConfigTable[kRGBA_float_GrPixelConfig].fFlags |=
+ ConfigInfo::kCanUseAsImageStorage_Flag;
+ fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseAsImageStorage_Flag;
+ }
+ }
+
#ifdef SK_DEBUG
// Make sure we initialized everything.
ConfigInfo defaultEntry;
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 496635d766..63843a5fc2 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -126,7 +126,9 @@ public:
return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderable_Flag);
}
}
-
+ bool canConfigBeImageStorage(GrPixelConfig config) const override {
+ return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kCanUseAsImageStorage_Flag);
+ }
bool canConfigBeFBOColorAttachment(GrPixelConfig config) const {
return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kFBOColorAttachment_Flag);
}
@@ -159,6 +161,11 @@ public:
bool getRenderbufferFormat(GrPixelConfig config, GrGLenum* internalFormat) const;
+ /** The format to use read/write a texture as an image in a shader */
+ GrGLenum getImageFormat(GrPixelConfig config) const {
+ return fConfigTable[config].fFormats.fSizedInternalFormat;
+ }
+
/**
* Gets an array of legal stencil formats. These formats are not guaranteed
* to be supported by the driver but are legal GLenum names given the GL
@@ -451,7 +458,6 @@ private:
GrGLenum fExternalFormat[kExternalFormatUsageCnt];
GrGLenum fExternalType;
-
// Either the base or sized internal format depending on the GL and config.
GrGLenum fInternalFormatTexImage;
GrGLenum fInternalFormatRenderbuffer;
@@ -489,6 +495,7 @@ private:
kFBOColorAttachment_Flag = 0x10,
kCanUseTexStorage_Flag = 0x20,
kCanUseWithTexelBuffer_Flag = 0x40,
+ kCanUseAsImageStorage_Flag = 0x80,
};
uint32_t fFlags;
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 94857789d9..af44af4338 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -217,6 +217,7 @@ GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context)
fCaps.reset(SkRef(ctx->caps()));
fHWBoundTextureUniqueIDs.reset(this->glCaps().glslCaps()->maxCombinedSamplers());
+ fHWBoundImageStorages.reset(this->glCaps().glslCaps()->maxCombinedImageStorages());
fHWBufferState[kVertex_GrBufferType].fGLTarget = GR_GL_ARRAY_BUFFER;
fHWBufferState[kIndex_GrBufferType].fGLTarget = GR_GL_ELEMENT_ARRAY_BUFFER;
@@ -557,6 +558,10 @@ void GrGLGpu::onResetContext(uint32_t resetBits) {
SkASSERT(this->caps()->shaderCaps()->texelBufferSupport());
fHWBufferTextures[b].fKnownBound = false;
}
+ for (int i = 0; i < fHWBoundImageStorages.count(); ++i) {
+ SkASSERT(this->caps()->shaderCaps()->imageLoadStoreSupport());
+ fHWBoundImageStorages[i].fTextureUniqueID.makeInvalid();
+ }
}
if (resetBits & kBlend_GrGLBackendState) {
@@ -3342,6 +3347,27 @@ void GrGLGpu::bindTexelBuffer(int unitIdx, GrPixelConfig texelConfig, GrGLBuffer
}
}
+void GrGLGpu::bindImageStorage(int unitIdx, GrIOType ioType, GrGLTexture *texture) {
+ SkASSERT(texture);
+ if (texture->uniqueID() != fHWBoundImageStorages[unitIdx].fTextureUniqueID ||
+ ioType != fHWBoundImageStorages[unitIdx].fIOType) {
+ GrGLenum access;
+ switch (ioType) {
+ case kRead_GrIOType:
+ access = GR_GL_READ_ONLY;
+ break;
+ case kWrite_GrIOType:
+ access = GR_GL_WRITE_ONLY;
+ break;
+ case kRW_GrIOType:
+ access = GR_GL_READ_WRITE;
+ break;
+ }
+ GrGLenum format = this->glCaps().getImageFormat(texture->config());
+ GL_CALL(BindImageTexture(unitIdx, texture->textureID(), 0, GR_GL_FALSE, 0, access, format));
+ }
+}
+
void GrGLGpu::generateMipmaps(const GrSamplerParams& params, bool allowSRGBInputs,
GrGLTexture* texture) {
SkASSERT(texture);
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index dff342d823..c6e7935ed0 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -62,6 +62,8 @@ public:
void bindTexelBuffer(int unitIdx, GrPixelConfig, GrGLBuffer*);
+ void bindImageStorage(int unitIdx, GrIOType, GrGLTexture *);
+
void generateMipmaps(const GrSamplerParams& params, bool allowSRGBInputs, GrGLTexture* texture);
bool onGetReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes,
@@ -569,6 +571,12 @@ private:
TriState fHWSRGBFramebuffer;
SkTArray<GrGpuResource::UniqueID, true> fHWBoundTextureUniqueIDs;
+ struct Image {
+ GrGpuResource::UniqueID fTextureUniqueID;
+ GrIOType fIOType;
+ };
+ SkTArray<Image, true> fHWBoundImageStorages;
+
struct BufferTexture {
BufferTexture() : fTextureID(0), fKnownBound(false),
fAttachedBufferUniqueID(SK_InvalidUniqueID),
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 820b55c7fe..f09b66869f 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -31,6 +31,7 @@ GrGLProgram::GrGLProgram(GrGLGpu* gpu,
GrGLuint programID,
const UniformInfoArray& uniforms,
const UniformInfoArray& samplers,
+ const UniformInfoArray& imageStorages,
const VaryingInfoArray& pathProcVaryings,
GrGLSLPrimitiveProcessor* geometryProcessor,
GrGLSLXferProcessor* xferProcessor,
@@ -46,6 +47,7 @@ GrGLProgram::GrGLProgram(GrGLGpu* gpu,
// Assign texture units to sampler uniforms one time up front.
GL_CALL(UseProgram(fProgramID));
fProgramDataManager.setSamplers(samplers);
+ fProgramDataManager.setImageStorages(imageStorages);
}
GrGLProgram::~GrGLProgram() {
@@ -161,6 +163,11 @@ void GrGLProgram::bindTextures(const GrProcessor& processor,
fGpu->bindTexelBuffer((*nextSamplerIdx)++, access.texelConfig(),
static_cast<GrGLBuffer*>(access.buffer()));
}
+ for (int i = 0; i < processor.numImageStorages(); ++i) {
+ const GrProcessor::ImageStorageAccess& access = processor.imageStorageAccess(i);
+ fGpu->bindImageStorage((*nextSamplerIdx)++, access.ioType(),
+ static_cast<GrGLTexture *>(access.texture()));
+ }
}
void GrGLProgram::generateMipmaps(const GrProcessor& processor,
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index d129ddaa3d..9c429782c5 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -102,9 +102,9 @@ public:
void generateMipmaps(const GrPrimitiveProcessor&, const GrPipeline&);
protected:
- typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
- typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
- typedef GrGLProgramDataManager::VaryingInfoArray VaryingInfoArray;
+ using UniformHandle = GrGLSLProgramDataManager::UniformHandle ;
+ using UniformInfoArray = GrGLProgramDataManager::UniformInfoArray;
+ using VaryingInfoArray = GrGLProgramDataManager::VaryingInfoArray;
GrGLProgram(GrGLGpu*,
const GrProgramDesc&,
@@ -112,6 +112,7 @@ protected:
GrGLuint programID,
const UniformInfoArray& uniforms,
const UniformInfoArray& samplers,
+ const UniformInfoArray& imageStorages,
const VaryingInfoArray&, // used for NVPR only currently
GrGLSLPrimitiveProcessor* geometryProcessor,
GrGLSLXferProcessor* xferProcessor,
diff --git a/src/gpu/gl/GrGLProgramDataManager.cpp b/src/gpu/gl/GrGLProgramDataManager.cpp
index 3245bd7185..863eab7abf 100644
--- a/src/gpu/gl/GrGLProgramDataManager.cpp
+++ b/src/gpu/gl/GrGLProgramDataManager.cpp
@@ -65,6 +65,16 @@ void GrGLProgramDataManager::setSamplers(const UniformInfoArray& samplers) const
}
}
+void GrGLProgramDataManager::setImageStorages(const UniformInfoArray& images) const {
+ for (int i = 0; i < images.count(); ++i) {
+ const UniformInfo& image = images[i];
+ SkASSERT(image.fVisibility);
+ if (kUnusedUniform != image.fLocation) {
+ GR_GL_CALL(fGpu->glInterface(), Uniform1i(image.fLocation, i));
+ }
+ }
+}
+
void GrGLProgramDataManager::set1i(UniformHandle u, int32_t i) const {
const Uniform& uni = fUniforms[u.toIndex()];
SkASSERT(uni.fType == kInt_GrSLType);
diff --git a/src/gpu/gl/GrGLProgramDataManager.h b/src/gpu/gl/GrGLProgramDataManager.h
index 0ef902c10b..62af4b8cc0 100644
--- a/src/gpu/gl/GrGLProgramDataManager.h
+++ b/src/gpu/gl/GrGLProgramDataManager.h
@@ -47,6 +47,7 @@ public:
void setSamplers(const UniformInfoArray& samplers) const;
+ void setImageStorages(const UniformInfoArray &images) const;
/** Functions for uploading uniform values. The varities ending in v can be used to upload to an
* array of uniforms. arrayCount must be <= the array count of the uniform.
diff --git a/src/gpu/gl/GrGLUniformHandler.cpp b/src/gpu/gl/GrGLUniformHandler.cpp
index 2def001f43..81755d552a 100644
--- a/src/gpu/gl/GrGLUniformHandler.cpp
+++ b/src/gpu/gl/GrGLUniformHandler.cpp
@@ -80,11 +80,38 @@ GrGLSLUniformHandler::SamplerHandle GrGLUniformHandler::addSampler(uint32_t visi
return GrGLSLUniformHandler::SamplerHandle(fSamplers.count() - 1);
}
+GrGLSLUniformHandler::ImageStorageHandle GrGLUniformHandler::addImageStorage(
+ uint32_t visibility, GrSLType type, GrImageStorageFormat format, GrSLMemoryModel model,
+ GrSLRestrict restrict, GrIOType ioType, const char* name) {
+ SkASSERT(name && strlen(name));
+ SkDEBUGCODE(static const uint32_t kVisMask = kVertex_GrShaderFlag | kFragment_GrShaderFlag);
+ SkASSERT(0 == (~kVisMask & visibility));
+ SkASSERT(0 != visibility);
+ SkString mangleName;
+ char prefix = 'u';
+ fProgramBuilder->nameVariable(&mangleName, prefix, name, true);
+
+ UniformInfo& imageStorage = fImageStorages.push_back();
+ imageStorage.fVariable.setName(mangleName);
+
+ SkASSERT(GrSLTypeIsImageStorage(type));
+ imageStorage.fVariable.setType(type);
+ imageStorage.fVariable.setTypeModifier(GrShaderVar::kUniform_TypeModifier);
+ imageStorage.fVariable.setImageStorageFormat(format);
+ imageStorage.fVariable.setMemoryModel(model);
+ imageStorage.fVariable.setRestrict(restrict);
+ imageStorage.fVariable.setIOType(ioType);
+ imageStorage.fVariable.setPrecision(kHigh_GrSLPrecision);
+ imageStorage.fLocation = -1;
+ imageStorage.fVisibility = visibility;
+ return GrGLSLUniformHandler::ImageStorageHandle(fImageStorages.count() - 1);
+}
+
void GrGLUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString* out) const {
for (int i = 0; i < fUniforms.count(); ++i) {
if (fUniforms[i].fVisibility & visibility) {
fUniforms[i].fVariable.appendDecl(fProgramBuilder->glslCaps(), out);
- out->append(";\n");
+ out->append(";");
}
}
for (int i = 0; i < fSamplers.count(); ++i) {
@@ -93,19 +120,29 @@ void GrGLUniformHandler::appendUniformDecls(GrShaderFlags visibility, SkString*
out->append(";\n");
}
}
+ for (int i = 0; i < fImageStorages.count(); ++i) {
+ if (fImageStorages[i].fVisibility & visibility) {
+ fImageStorages[i].fVariable.appendDecl(fProgramBuilder->glslCaps(), out);
+ out->append(";");
+ }
+ }
}
void GrGLUniformHandler::bindUniformLocations(GrGLuint programID, const GrGLCaps& caps) {
if (caps.bindUniformLocationSupport()) {
- int uniformCnt = fUniforms.count();
- for (int i = 0; i < uniformCnt; ++i) {
- GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_str()));
- fUniforms[i].fLocation = i;
+ int currUniform = 0;
+ for (int i = 0; i < fUniforms.count(); ++i, ++currUniform) {
+ GL_CALL(BindUniformLocation(programID, currUniform, fUniforms[i].fVariable.c_str()));
+ fUniforms[i].fLocation = currUniform;
}
- for (int i = 0; i < fSamplers.count(); ++i) {
- GrGLint location = i + uniformCnt;
- GL_CALL(BindUniformLocation(programID, location, fSamplers[i].fVariable.c_str()));
- fSamplers[i].fLocation = location;
+ for (int i = 0; i < fSamplers.count(); ++i, ++currUniform) {
+ GL_CALL(BindUniformLocation(programID, currUniform, fSamplers[i].fVariable.c_str()));
+ fSamplers[i].fLocation = currUniform;
+ }
+ for (int i = 0; i < fImageStorages.count(); ++i) {
+ GL_CALL(BindUniformLocation(programID, currUniform,
+ fImageStorages[i].fVariable.c_str()));
+ fImageStorages[i].fLocation = currUniform;
}
}
}
@@ -123,6 +160,12 @@ void GrGLUniformHandler::getUniformLocations(GrGLuint programID, const GrGLCaps&
GL_CALL_RET(location, GetUniformLocation(programID, fSamplers[i].fVariable.c_str()));
fSamplers[i].fLocation = location;
}
+ for (int i = 0; i < fImageStorages.count(); ++i) {
+ GrGLint location;
+ GL_CALL_RET(location, GetUniformLocation(programID,
+ fImageStorages[i].fVariable.c_str()));
+ fImageStorages[i].fLocation = location;
+ }
}
}
diff --git a/src/gpu/gl/GrGLUniformHandler.h b/src/gpu/gl/GrGLUniformHandler.h
index d3aa2f8358..da7b13c4f5 100644
--- a/src/gpu/gl/GrGLUniformHandler.h
+++ b/src/gpu/gl/GrGLUniformHandler.h
@@ -29,7 +29,8 @@ private:
explicit GrGLUniformHandler(GrGLSLProgramBuilder* program)
: INHERITED(program)
, fUniforms(kUniformsPerBlock)
- , fSamplers(kUniformsPerBlock) {}
+ , fSamplers(kUniformsPerBlock)
+ , fImageStorages(kUniformsPerBlock) {}
UniformHandle internalAddUniformArray(uint32_t visibility,
GrSLType type,
@@ -46,10 +47,18 @@ private:
return fSamplers[handle.toIndex()].fVariable;
}
+ ImageStorageHandle addImageStorage(uint32_t visibility, GrSLType, GrImageStorageFormat,
+ GrSLMemoryModel, GrSLRestrict, GrIOType,
+ const char* name) override;
+
GrSwizzle samplerSwizzle(SamplerHandle handle) const override {
return fSamplerSwizzles[handle.toIndex()];
}
+ const GrShaderVar& imageStorageVariable(ImageStorageHandle handle) const override {
+ return fImageStorages[handle.toIndex()].fVariable;
+ }
+
void appendUniformDecls(GrShaderFlags visibility, SkString*) const override;
// Manually set uniform locations for all our uniforms.
@@ -66,6 +75,7 @@ private:
UniformInfoArray fUniforms;
UniformInfoArray fSamplers;
SkTArray<GrSwizzle> fSamplerSwizzles;
+ UniformInfoArray fImageStorages;
friend class GrGLProgramBuilder;
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index a1ad572a86..a774570b68 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -237,6 +237,7 @@ GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
programID,
fUniformHandler.fUniforms,
fUniformHandler.fSamplers,
+ fUniformHandler.fImageStorages,
fVaryingHandler.fPathProcVaryingInfos,
fGeometryProcessor,
fXferProcessor,