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/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index 820b428..de4ab9e 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -27,7 +27,7 @@
bool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that) const {
if (this->classID() != that.classID() ||
- !this->hasSameSamplers(that)) {
+ !this->hasSameSamplersAndAccesses(that)) {
return false;
}
if (!this->hasSameTransforms(that)) {
diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp
index 1e100e4..f4f7ccb 100644
--- a/src/gpu/GrProcessor.cpp
+++ b/src/gpu/GrProcessor.cpp
@@ -122,7 +122,12 @@
void GrProcessor::addBufferAccess(const BufferAccess* access) {
fBufferAccesses.push_back(access);
- this->addGpuResource(access->getProgramBuffer());
+ this->addGpuResource(access->programBuffer());
+}
+
+void GrProcessor::addImageStorageAccess(const ImageStorageAccess* access) {
+ fImageStorageAccesses.push_back(access);
+ this->addGpuResource(access->programTexture());
}
void* GrProcessor::operator new(size_t size) {
@@ -133,9 +138,10 @@
return MemoryPoolAccessor().pool()->release(target);
}
-bool GrProcessor::hasSameSamplers(const GrProcessor& that) const {
+bool GrProcessor::hasSameSamplersAndAccesses(const GrProcessor &that) const {
if (this->numTextureSamplers() != that.numTextureSamplers() ||
- this->numBuffers() != that.numBuffers()) {
+ this->numBuffers() != that.numBuffers() ||
+ this->numImageStorages() != that.numImageStorages()) {
return false;
}
for (int i = 0; i < this->numTextureSamplers(); ++i) {
@@ -148,6 +154,11 @@
return false;
}
}
+ for (int i = 0; i < this->numImageStorages(); ++i) {
+ if (this->imageStorageAccess(i) != that.imageStorageAccess(i)) {
+ return false;
+ }
+ }
return true;
}
@@ -189,6 +200,37 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
+GrProcessor::ImageStorageAccess::ImageStorageAccess(sk_sp<GrTexture> texture, GrIOType ioType,
+ GrSLMemoryModel memoryModel,
+ GrSLRestrict restrict,
+ GrShaderFlags visibility) {
+ SkASSERT(texture);
+ fTexture.set(texture.release(), ioType);
+ fMemoryModel = memoryModel;
+ fRestrict = restrict;
+ fVisibility = visibility;
+ // We currently infer this from the config. However, we could allow the client to specify
+ // a format that is different but compatible with the config.
+ switch (fTexture.get()->config()) {
+ case kRGBA_8888_GrPixelConfig:
+ fFormat = GrImageStorageFormat::kRGBA8;
+ break;
+ case kRGBA_8888_sint_GrPixelConfig:
+ fFormat = GrImageStorageFormat::kRGBA8i;
+ break;
+ case kRGBA_half_GrPixelConfig:
+ fFormat = GrImageStorageFormat::kRGBA16f;
+ break;
+ case kRGBA_float_GrPixelConfig:
+ fFormat = GrImageStorageFormat::kRGBA32f;
+ break;
+ default:
+ SkFAIL("Config is not (yet) supported as image storage.");
+ break;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
// Initial static variable from GrXPFactory
-int32_t GrXPFactory::gCurrXPFClassID =
- GrXPFactory::kIllegalXPFClassID;
+int32_t GrXPFactory::gCurrXPFClassID = GrXPFactory::kIllegalXPFClassID;
diff --git a/src/gpu/GrProgramDesc.cpp b/src/gpu/GrProgramDesc.cpp
index cdbbc23..9f3278c 100644
--- a/src/gpu/GrProgramDesc.cpp
+++ b/src/gpu/GrProgramDesc.cpp
@@ -15,48 +15,88 @@
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLCaps.h"
-static uint16_t sampler_key(GrSLType samplerType, GrPixelConfig config, GrShaderFlags visibility,
- const GrGLSLCaps& caps) {
- enum {
- kFirstSamplerType = kTexture2DSampler_GrSLType,
- kLastSamplerType = kBufferSampler_GrSLType,
- kSamplerTypeKeyBits = 4
- };
- GR_STATIC_ASSERT(kLastSamplerType - kFirstSamplerType < (1 << kSamplerTypeKeyBits));
+enum {
+ kSamplerOrImageTypeKeyBits = 4
+};
- SkASSERT((int)samplerType >= kFirstSamplerType && (int)samplerType <= kLastSamplerType);
- int samplerTypeKey = samplerType - kFirstSamplerType;
+static inline uint16_t image_storage_or_sampler_uniform_type_key(GrSLType type ) {
+ int value = UINT16_MAX;
+ switch (type) {
+ case kTexture2DSampler_GrSLType:
+ value = 0;
+ break;
+ case kITexture2DSampler_GrSLType:
+ value = 1;
+ break;
+ case kTextureExternalSampler_GrSLType:
+ value = 2;
+ break;
+ case kTexture2DRectSampler_GrSLType:
+ value = 3;
+ break;
+ case kBufferSampler_GrSLType:
+ value = 4;
+ break;
+ case kImageStorage2D_GrSLType:
+ value = 5;
+ break;
+ case kIImageStorage2D_GrSLType:
+ value = 6;
+ break;
- return SkToU16(caps.configTextureSwizzle(config).asKey() |
- (samplerTypeKey << 8) |
- (caps.samplerPrecision(config, visibility) << (8 + kSamplerTypeKeyBits)));
+ default:
+ break;
+ }
+ SkASSERT((value & ((1 << kSamplerOrImageTypeKeyBits) - 1)) == value);
+ return value;
}
-static void add_sampler_keys(GrProcessorKeyBuilder* b, const GrProcessor& proc,
- const GrGLSLCaps& caps) {
+static uint16_t sampler_key(GrSLType samplerType, GrPixelConfig config, GrShaderFlags visibility,
+ const GrGLSLCaps& caps) {
+ int samplerTypeKey = image_storage_or_sampler_uniform_type_key(samplerType);
+
+ GR_STATIC_ASSERT(1 == sizeof(caps.configTextureSwizzle(config).asKey()));
+ return SkToU16(samplerTypeKey |
+ caps.configTextureSwizzle(config).asKey() << kSamplerOrImageTypeKeyBits |
+ (caps.samplerPrecision(config, visibility) << (8 + kSamplerOrImageTypeKeyBits)));
+}
+
+static uint16_t storage_image_key(const GrProcessor::ImageStorageAccess& imageAccess) {
+ GrSLType type = imageAccess.texture()->texturePriv().imageStorageType();
+ return image_storage_or_sampler_uniform_type_key(type) |
+ (int)imageAccess.format() << kSamplerOrImageTypeKeyBits;
+}
+
+static void add_sampler_and_image_keys(GrProcessorKeyBuilder* b, const GrProcessor& proc,
+ const GrGLSLCaps& caps) {
int numTextureSamplers = proc.numTextureSamplers();
- int numSamplers = numTextureSamplers + proc.numBuffers();
- // Need two bytes per key (swizzle, sampler type, and precision).
- int word32Count = (numSamplers + 1) / 2;
+ int numBuffers = proc.numBuffers();
+ int numImageStorages = proc.numImageStorages();
+ int numUniforms = numTextureSamplers + numBuffers + numImageStorages;
+ // Need two bytes per key.
+ int word32Count = (numUniforms + 1) / 2;
if (0 == word32Count) {
return;
}
uint16_t* k16 = SkTCast<uint16_t*>(b->add32n(word32Count));
- int i = 0;
- for (; i < numTextureSamplers; ++i) {
- const GrProcessor::TextureSampler& textureSampler = proc.textureSampler(i);
- const GrTexture* tex = textureSampler.texture();
- k16[i] = sampler_key(tex->texturePriv().samplerType(), tex->config(),
- textureSampler.visibility(), caps);
+ int j = 0;
+ for (int i = 0; i < numTextureSamplers; ++i, ++j) {
+ const GrProcessor::TextureSampler& sampler = proc.textureSampler(i);
+ const GrTexture* tex = sampler.texture();
+ k16[j] = sampler_key(tex->texturePriv().samplerType(), tex->config(), sampler.visibility(),
+ caps);
}
- for (; i < numSamplers; ++i) {
- const GrProcessor::BufferAccess& access = proc.bufferAccess(i - numTextureSamplers);
- k16[i] = sampler_key(kBufferSampler_GrSLType, access.texelConfig(),
- access.visibility(), caps);
+ for (int i = 0; i < numBuffers; ++i, ++j) {
+ const GrProcessor::BufferAccess& access = proc.bufferAccess(i);
+ k16[j] = sampler_key(kBufferSampler_GrSLType, access.texelConfig(), access.visibility(),
+ caps);
}
- // zero the last 16 bits if the number of samplers is odd.
- if (numSamplers & 0x1) {
- k16[numSamplers] = 0;
+ for (int i = 0; i < numImageStorages; ++i, ++j) {
+ k16[j] = storage_image_key(proc.imageStorageAccess(i));
+ }
+ // zero the last 16 bits if the number of uniforms for samplers and image storages is odd.
+ if (numUniforms & 0x1) {
+ k16[numUniforms] = 0;
}
}
@@ -82,7 +122,7 @@
return false;
}
- add_sampler_keys(b, proc, glslCaps);
+ add_sampler_and_image_keys(b, proc, glslCaps);
uint32_t* key = b->add32n(2);
key[0] = (classID << 16) | SkToU32(processorKeySize);
diff --git a/src/gpu/GrShaderVar.cpp b/src/gpu/GrShaderVar.cpp
index ef305cb..75142ca 100644
--- a/src/gpu/GrShaderVar.cpp
+++ b/src/gpu/GrShaderVar.cpp
@@ -9,14 +9,86 @@
#include "GrShaderVar.h"
#include "glsl/GrGLSLCaps.h"
+static const char* type_modifier_string(GrShaderVar::TypeModifier t) {
+ switch (t) {
+ case GrShaderVar::kNone_TypeModifier: return "";
+ case GrShaderVar::kIn_TypeModifier: return "in";
+ case GrShaderVar::kInOut_TypeModifier: return "inout";
+ case GrShaderVar::kOut_TypeModifier: return "out";
+ case GrShaderVar::kUniform_TypeModifier: return "uniform";
+ }
+ SkFAIL("Unknown shader variable type modifier.");
+ return "";
+}
+
+void GrShaderVar::setImageStorageFormat(GrImageStorageFormat format) {
+ const char* formatStr = nullptr;
+ switch (format) {
+ case GrImageStorageFormat::kRGBA8:
+ formatStr = "rgba8";
+ break;
+ case GrImageStorageFormat::kRGBA8i:
+ formatStr = "rgba8i";
+ break;
+ case GrImageStorageFormat::kRGBA16f:
+ formatStr = "rgba16f";
+ break;
+ case GrImageStorageFormat::kRGBA32f:
+ formatStr = "rgba32f";
+ break;
+ }
+ this->addLayoutQualifier(formatStr);
+ SkASSERT(formatStr);
+}
+
+void GrShaderVar::setMemoryModel(GrSLMemoryModel model) {
+ switch (model) {
+ case GrSLMemoryModel::kNone:
+ return;
+ case GrSLMemoryModel::kCoherent:
+ this->addModifier("coherent");
+ return;
+ case GrSLMemoryModel::kVolatile:
+ this->addModifier("volatile");
+ return;
+ }
+ SkFAIL("Unknown memory model.");
+}
+
+void GrShaderVar::setRestrict(GrSLRestrict restrict) {
+ switch (restrict) {
+ case GrSLRestrict::kNo:
+ return;
+ case GrSLRestrict::kYes:
+ this->addModifier("restrict");
+ return;
+ }
+ SkFAIL("Unknown restrict.");
+}
+
+void GrShaderVar::setIOType(GrIOType ioType) {
+ switch (ioType) {
+ case kRW_GrIOType:
+ return;
+ case kRead_GrIOType:
+ this->addModifier("readonly");
+ return;
+ case kWrite_GrIOType:
+ this->addModifier("writeonly");
+ return;
+ }
+ SkFAIL("Unknown io type.");
+}
+
void GrShaderVar::appendDecl(const GrGLSLCaps* glslCaps, SkString* out) const {
SkASSERT(kDefault_GrSLPrecision == fPrecision || GrSLTypeAcceptsPrecision(fType));
+ SkString layout = fLayoutQualifier;
if (!fLayoutQualifier.isEmpty()) {
out->appendf("layout(%s) ", fLayoutQualifier.c_str());
}
out->append(fExtraModifiers);
if (this->getTypeModifier() != kNone_TypeModifier) {
- out->append(TypeModifierString(this->getTypeModifier()));
+ out->append(type_modifier_string(this->getTypeModifier()));
out->append(" ");
}
GrSLType effectiveType = this->getType();
diff --git a/src/gpu/GrTexturePriv.h b/src/gpu/GrTexturePriv.h
index d68eb79..0420611 100644
--- a/src/gpu/GrTexturePriv.h
+++ b/src/gpu/GrTexturePriv.h
@@ -49,6 +49,14 @@
return fTexture->fMaxMipMapLevel;
}
+ GrSLType imageStorageType() const {
+ if (GrPixelConfigIsSint(fTexture->config())) {
+ return kIImageStorage2D_GrSLType;
+ } else {
+ return kImageStorage2D_GrSLType;
+ }
+ }
+
GrSLType samplerType() const { return fTexture->fSamplerType; }
/** The filter used is clamped to this value in GrProcessor::TextureSampler. */
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 3e9f82a..c4f7560 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -324,16 +324,29 @@
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 @@
}
}
+ // 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 496635d..63843a5 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -126,7 +126,9 @@
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 @@
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 @@
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 @@
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 9485778..af44af4 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -217,6 +217,7 @@
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 @@
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::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 dff342d..c6e7935 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -62,6 +62,8 @@
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 @@
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 820b55c..f09b668 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -31,6 +31,7 @@
GrGLuint programID,
const UniformInfoArray& uniforms,
const UniformInfoArray& samplers,
+ const UniformInfoArray& imageStorages,
const VaryingInfoArray& pathProcVaryings,
GrGLSLPrimitiveProcessor* geometryProcessor,
GrGLSLXferProcessor* xferProcessor,
@@ -46,6 +47,7 @@
// 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 @@
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 d129dda..9c42978 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -102,9 +102,9 @@
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 @@
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 3245bd7..863eab7 100644
--- a/src/gpu/gl/GrGLProgramDataManager.cpp
+++ b/src/gpu/gl/GrGLProgramDataManager.cpp
@@ -65,6 +65,16 @@
}
}
+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 0ef902c..62af4b8 100644
--- a/src/gpu/gl/GrGLProgramDataManager.h
+++ b/src/gpu/gl/GrGLProgramDataManager.h
@@ -47,6 +47,7 @@
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 2def001..81755d5 100644
--- a/src/gpu/gl/GrGLUniformHandler.cpp
+++ b/src/gpu/gl/GrGLUniformHandler.cpp
@@ -80,11 +80,38 @@
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 @@
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 @@
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 d3aa2f8..da7b13c 100644
--- a/src/gpu/gl/GrGLUniformHandler.h
+++ b/src/gpu/gl/GrGLUniformHandler.h
@@ -29,7 +29,8 @@
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 @@
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 @@
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 a1ad572..a774570 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -237,6 +237,7 @@
programID,
fUniformHandler.fUniforms,
fUniformHandler.fSamplers,
+ fUniformHandler.fImageStorages,
fVaryingHandler.fPathProcVaryingInfos,
fGeometryProcessor,
fXferProcessor,
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;
};
/**
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index abc0dc9..7b40e0d 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -37,6 +37,8 @@
return SkToBool(ConfigInfo::kRenderable_Flag & fConfigTable[config].fOptimalFlags);
}
+ bool canConfigBeImageStorage(GrPixelConfig) const override { return false; }
+
bool isConfigTexturableLinearly(GrPixelConfig config) const {
return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fLinearFlags);
}
diff --git a/src/gpu/vk/GrVkPipelineState.cpp b/src/gpu/vk/GrVkPipelineState.cpp
index 2d53cd8..75b8baa 100644
--- a/src/gpu/vk/GrVkPipelineState.cpp
+++ b/src/gpu/vk/GrVkPipelineState.cpp
@@ -174,6 +174,8 @@
static void append_texture_bindings(const GrProcessor& processor,
SkTArray<const GrProcessor::TextureSampler*>* textureBindings) {
+ // We don't support image storages in VK.
+ SkASSERT(!processor.numImageStorages());
if (int numTextureSamplers = processor.numTextureSamplers()) {
const GrProcessor::TextureSampler** bindings =
textureBindings->push_back_n(numTextureSamplers);
diff --git a/src/gpu/vk/GrVkUniformHandler.cpp b/src/gpu/vk/GrVkUniformHandler.cpp
index 3998c0f..8c4f851 100644
--- a/src/gpu/vk/GrVkUniformHandler.cpp
+++ b/src/gpu/vk/GrVkUniformHandler.cpp
@@ -45,6 +45,8 @@
case kBufferSampler_GrSLType:
case kTexture2D_GrSLType:
case kSampler_GrSLType:
+ case kImageStorage2D_GrSLType:
+ case kIImageStorage2D_GrSLType:
break;
}
SkFAIL("Unexpected type");
@@ -86,6 +88,8 @@
case kBufferSampler_GrSLType:
case kTexture2D_GrSLType:
case kSampler_GrSLType:
+ case kImageStorage2D_GrSLType:
+ case kIImageStorage2D_GrSLType:
break;
}
SkFAIL("Unexpected type");
@@ -158,7 +162,7 @@
uni.fVariable.setTypeModifier(GrShaderVar::kNone_TypeModifier);
uint32_t* currentOffset = kVertex_GrShaderFlag == visibility ? &fCurrentVertexUBOOffset
- : &fCurrentFragmentUBOOffset;
+ : &fCurrentFragmentUBOOffset;
get_ubo_aligned_offset(&uni.fUBOffset, currentOffset, type, arrayCount);
if (outName) {
diff --git a/src/gpu/vk/GrVkUniformHandler.h b/src/gpu/vk/GrVkUniformHandler.h
index e5d4a4c..808eed7 100644
--- a/src/gpu/vk/GrVkUniformHandler.h
+++ b/src/gpu/vk/GrVkUniformHandler.h
@@ -76,6 +76,19 @@
return fSamplers[handle.toIndex()].fVisibility;
}
+ ImageStorageHandle addImageStorage(uint32_t visibility, GrSLType, GrImageStorageFormat,
+ GrSLMemoryModel, GrSLRestrict, GrIOType,
+ const char* name) override {
+ SkFAIL("Image storages not implemented for Vulkan.");
+ return 0;
+ }
+
+ const GrShaderVar& imageStorageVariable(ImageStorageHandle handle) const override {
+ SkFAIL("Image storages not implemented for Vulkan.");
+ static const GrShaderVar* gVar = nullptr;
+ return *gVar;
+ }
+
void appendUniformDecls(GrShaderFlags, SkString*) const override;
bool hasVertexUniforms() const { return fCurrentVertexUBOOffset > 0; }
diff --git a/src/gpu/vk/GrVkVaryingHandler.cpp b/src/gpu/vk/GrVkVaryingHandler.cpp
index 9bab292..d7d08c9 100644
--- a/src/gpu/vk/GrVkVaryingHandler.cpp
+++ b/src/gpu/vk/GrVkVaryingHandler.cpp
@@ -47,6 +47,10 @@
return 0;
case kSampler_GrSLType:
return 0;
+ case kImageStorage2D_GrSLType:
+ return 0;
+ case kIImageStorage2D_GrSLType:
+ return 0;
}
SkFAIL("Unexpected type");
return -1;
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
index 7c26287..5b74724 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -455,11 +455,26 @@
void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers,
bool globalContext) {
+ if (modifiers.fFlags & Modifiers::kFlat_Flag) {
+ this->write("flat ");
+ }
if (modifiers.fFlags & Modifiers::kNoPerspective_Flag) {
this->write("noperspective ");
}
- if (modifiers.fFlags & Modifiers::kFlat_Flag) {
- this->write("flat ");
+ if (modifiers.fFlags & Modifiers::kReadOnly_Flag) {
+ this->write("readonly ");
+ }
+ if (modifiers.fFlags & Modifiers::kWriteOnly_Flag) {
+ this->write("writeonly ");
+ }
+ if (modifiers.fFlags & Modifiers::kCoherent_Flag) {
+ this->write("coherent ");
+ }
+ if (modifiers.fFlags & Modifiers::kVolatile_Flag) {
+ this->write("volatile ");
+ }
+ if (modifiers.fFlags & Modifiers::kRestrict_Flag) {
+ this->write("restrict ");
}
SkString layout = modifiers.fLayout.description();
if (layout.size()) {
diff --git a/src/sksl/SkSLParser.cpp b/src/sksl/SkSLParser.cpp
index 3920b00..cd0ae6a 100644
--- a/src/sksl/SkSLParser.cpp
+++ b/src/sksl/SkSLParser.cpp
@@ -601,7 +601,8 @@
pushConstant);
}
-/* layout? (UNIFORM | CONST | IN | OUT | INOUT | LOWP | MEDIUMP | HIGHP | FLAT | NOPERSPECTIVE)* */
+/* layout? (UNIFORM | CONST | IN | OUT | INOUT | LOWP | MEDIUMP | HIGHP | FLAT | NOPERSPECTIVE |
+ READONLY | WRITEONLY | COHERENT | VOLATILE | RESTRICT)* */
Modifiers Parser::modifiers() {
Layout layout = this->layout();
int flags = 0;
@@ -649,6 +650,26 @@
this->nextToken();
flags |= Modifiers::kNoPerspective_Flag;
break;
+ case Token::READONLY:
+ this->nextToken();
+ flags |= Modifiers::kReadOnly_Flag;
+ break;
+ case Token::WRITEONLY:
+ this->nextToken();
+ flags |= Modifiers::kWriteOnly_Flag;
+ break;
+ case Token::COHERENT:
+ this->nextToken();
+ flags |= Modifiers::kCoherent_Flag;
+ break;
+ case Token::VOLATILE:
+ this->nextToken();
+ flags |= Modifiers::kVolatile_Flag;
+ break;
+ case Token::RESTRICT:
+ this->nextToken();
+ flags |= Modifiers::kRestrict_Flag;
+ break;
default:
return Modifiers(layout, flags);
}
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp
index 62c0c50..b2857f4 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.cpp
+++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp
@@ -2460,6 +2460,13 @@
for (size_t i = 0; i < decl.fVars.size(); i++) {
const VarDeclaration& varDecl = decl.fVars[i];
const Variable* var = varDecl.fVar;
+ // These haven't been implemented in our SPIR-V generator yet and we only currently use them
+ // in the OpenGL backend.
+ ASSERT(!(var->fModifiers.fFlags & (Modifiers::kReadOnly_Flag |
+ Modifiers::kWriteOnly_Flag |
+ Modifiers::kCoherent_Flag |
+ Modifiers::kVolatile_Flag |
+ Modifiers::kRestrict_Flag)));
if (var->fModifiers.fLayout.fBuiltin == BUILTIN_IGNORE) {
continue;
}
@@ -2514,6 +2521,13 @@
void SPIRVCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, SkWStream& out) {
for (const auto& varDecl : decl.fVars) {
const Variable* var = varDecl.fVar;
+ // These haven't been implemented in our SPIR-V generator yet and we only currently use them
+ // in the OpenGL backend.
+ ASSERT(!(var->fModifiers.fFlags & (Modifiers::kReadOnly_Flag |
+ Modifiers::kWriteOnly_Flag |
+ Modifiers::kCoherent_Flag |
+ Modifiers::kVolatile_Flag |
+ Modifiers::kRestrict_Flag)));
SpvId id = this->nextId();
fVariableMap[var] = id;
SpvId type = this->getPointerType(var->fType, SpvStorageClassFunction);
diff --git a/src/sksl/SkSLToken.h b/src/sksl/SkSLToken.h
index 6fe130f..5c8c2bd 100644
--- a/src/sksl/SkSLToken.h
+++ b/src/sksl/SkSLToken.h
@@ -96,6 +96,11 @@
UNIFORM,
FLAT,
NOPERSPECTIVE,
+ READONLY,
+ WRITEONLY,
+ COHERENT,
+ VOLATILE,
+ RESTRICT,
STRUCT,
LAYOUT,
DIRECTIVE,
diff --git a/src/sksl/ir/SkSLModifiers.h b/src/sksl/ir/SkSLModifiers.h
index dbb9b6b..c7a5639 100644
--- a/src/sksl/ir/SkSLModifiers.h
+++ b/src/sksl/ir/SkSLModifiers.h
@@ -17,16 +17,21 @@
*/
struct Modifiers {
enum Flag {
- kNo_Flag = 0,
- kConst_Flag = 1,
- kIn_Flag = 2,
- kOut_Flag = 4,
- kLowp_Flag = 8,
- kMediump_Flag = 16,
- kHighp_Flag = 32,
- kUniform_Flag = 64,
- kFlat_Flag = 128,
- kNoPerspective_Flag = 256
+ kNo_Flag = 0,
+ kConst_Flag = 1,
+ kIn_Flag = 2,
+ kOut_Flag = 4,
+ kLowp_Flag = 8,
+ kMediump_Flag = 16,
+ kHighp_Flag = 32,
+ kUniform_Flag = 64,
+ kFlat_Flag = 128,
+ kNoPerspective_Flag = 256,
+ kReadOnly_Flag = 512,
+ kWriteOnly_Flag = 1024,
+ kCoherent_Flag = 2048,
+ kVolatile_Flag = 4096,
+ kRestrict_Flag = 8192
};
Modifiers()
@@ -60,6 +65,21 @@
if (fFlags & kNoPerspective_Flag) {
result += "noperspective ";
}
+ if (fFlags & kReadOnly_Flag) {
+ result += "readonly ";
+ }
+ if (fFlags & kWriteOnly_Flag) {
+ result += "writeonly ";
+ }
+ if (fFlags & kCoherent_Flag) {
+ result += "coherent ";
+ }
+ if (fFlags & kVolatile_Flag) {
+ result += "volatile ";
+ }
+ if (fFlags & kRestrict_Flag) {
+ result += "restrict ";
+ }
if ((fFlags & kIn_Flag) && (fFlags & kOut_Flag)) {
result += "inout ";
diff --git a/src/sksl/lex.sksl.c b/src/sksl/lex.sksl.c
index 710b67b..4cff376 100644
--- a/src/sksl/lex.sksl.c
+++ b/src/sksl/lex.sksl.c
@@ -4,7 +4,7 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
-
+
#line 3 "lex.sksl.c"
#define YY_INT_ALIGNED short int
@@ -13,8 +13,8 @@
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 35
+#define YY_FLEX_MINOR_VERSION 6
+#define YY_FLEX_SUBMINOR_VERSION 0
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
@@ -52,7 +52,6 @@
typedef uint16_t flex_uint16_t;
typedef int32_t flex_int32_t;
typedef uint32_t flex_uint32_t;
-typedef uint64_t flex_uint64_t;
#else
typedef signed char flex_int8_t;
typedef short int flex_int16_t;
@@ -60,7 +59,6 @@
typedef unsigned char flex_uint8_t;
typedef unsigned short int flex_uint16_t;
typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
/* Limits of integral types. */
#ifndef INT8_MIN
@@ -91,6 +89,8 @@
#define UINT32_MAX (4294967295U)
#endif
+#endif /* ! C99 */
+
#endif /* ! FLEXINT_H */
#ifdef __cplusplus
@@ -164,7 +164,15 @@
/* Size of default input buffer. */
#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
#endif
/* The state buf must be large enough to hold one state per character in the main buffer.
@@ -194,11 +202,18 @@
*/
#define YY_LESS_LINENO(n) \
do { \
- yy_size_t yyl;\
+ int yyl;\
for ( yyl = n; yyl < yyleng; ++yyl )\
if ( yytext[yyl] == '\n' )\
--yylineno;\
}while(0)
+ #define YY_LINENO_REWIND_TO(dst) \
+ do {\
+ const char *p;\
+ for ( p = yy_cp-1; p >= (dst); --p)\
+ if ( *p == '\n' )\
+ --yylineno;\
+ }while(0)
/* Return all but the first "n" matched characters back to the input stream. */
#define yyless(n) \
@@ -233,7 +248,7 @@
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
- yy_size_t yy_n_chars;
+ int yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
@@ -353,6 +368,9 @@
static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
static int yy_get_next_buffer (yyscan_t yyscanner );
+#if defined(__GNUC__) && __GNUC__ >= 3
+__attribute__((__noreturn__))
+#endif
static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
/* Done after the current pattern has been matched and before the
@@ -360,13 +378,13 @@
*/
#define YY_DO_BEFORE_ACTION \
yyg->yytext_ptr = yy_bp; \
- yyleng = (yy_size_t) (yy_cp - yy_bp); \
+ yyleng = (size_t) (yy_cp - yy_bp); \
yyg->yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 84
-#define YY_END_OF_BUFFER 85
+#define YY_NUM_RULES 89
+#define YY_END_OF_BUFFER 90
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -374,34 +392,37 @@
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[205] =
+static yyconst flex_int16_t yy_accept[239] =
{ 0,
- 0, 0, 85, 83, 82, 82, 56, 83, 30, 46,
- 51, 32, 33, 44, 42, 39, 43, 38, 45, 4,
- 4, 58, 79, 63, 59, 62, 57, 36, 37, 50,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 34, 49, 35,
- 52, 82, 61, 31, 30, 70, 55, 75, 68, 40,
- 66, 41, 67, 1, 0, 80, 69, 2, 4, 0,
- 0, 47, 65, 60, 64, 48, 74, 54, 30, 30,
- 30, 12, 30, 30, 30, 30, 30, 8, 17, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 0, 0, 90, 88, 87, 87, 61, 88, 35, 51,
+ 56, 37, 38, 49, 47, 44, 48, 43, 50, 4,
+ 4, 63, 84, 68, 64, 67, 62, 41, 42, 55,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 39, 54,
+ 40, 57, 87, 66, 36, 35, 75, 60, 80, 73,
+ 45, 71, 46, 72, 1, 0, 85, 74, 2, 4,
+ 0, 0, 52, 70, 65, 69, 53, 79, 59, 35,
+ 35, 35, 12, 35, 35, 35, 35, 35, 8, 17,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 73, 53, 31, 78, 0, 0, 0, 80, 1, 0,
- 0, 3, 5, 71, 72, 77, 30, 30, 30, 30,
- 30, 30, 10, 30, 30, 30, 30, 30, 30, 18,
- 30, 30, 30, 30, 30, 30, 76, 0, 1, 81,
- 0, 0, 2, 30, 30, 30, 30, 9, 30, 25,
- 30, 30, 30, 22, 30, 30, 30, 30, 30, 6,
- 30, 30, 0, 1, 13, 21, 30, 30, 7, 24,
- 19, 30, 30, 30, 30, 30, 30, 30, 11, 30,
- 30, 28, 30, 30, 30, 16, 27, 30, 30, 15,
- 23, 30, 30, 20, 14, 30, 30, 30, 29, 30,
+ 35, 35, 35, 78, 58, 36, 83, 0, 0, 0,
+ 85, 1, 0, 0, 3, 5, 76, 77, 82, 35,
+ 35, 35, 35, 35, 35, 35, 10, 35, 35, 35,
+ 35, 35, 35, 18, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 81, 0, 1, 86, 0, 0,
+ 2, 35, 35, 35, 35, 35, 9, 35, 25, 35,
+ 35, 35, 22, 35, 35, 35, 35, 35, 35, 35,
+ 6, 35, 35, 35, 35, 0, 1, 13, 35, 21,
+ 35, 35, 7, 24, 19, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 11, 35, 35, 35, 35,
- 30, 30, 26, 0
+ 33, 35, 35, 35, 35, 35, 16, 32, 35, 35,
+ 35, 35, 35, 15, 23, 35, 35, 35, 35, 20,
+ 35, 35, 29, 14, 35, 35, 27, 31, 30, 35,
+ 35, 34, 28, 35, 35, 35, 26, 0
} ;
-static yyconst flex_int32_t yy_ec[256] =
+static yyconst YY_CHAR yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
@@ -433,7 +454,7 @@
1, 1, 1, 1, 1
} ;
-static yyconst flex_int32_t yy_meta[57] =
+static yyconst YY_CHAR yy_meta[57] =
{ 0,
1, 1, 2, 1, 1, 3, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 4, 4, 1, 1,
@@ -443,101 +464,113 @@
3, 3, 1, 1, 1, 1
} ;
-static yyconst flex_int16_t yy_base[211] =
+static yyconst flex_uint16_t yy_base[245] =
{ 0,
- 0, 0, 273, 274, 55, 57, 250, 0, 0, 249,
- 53, 274, 274, 248, 50, 274, 49, 47, 57, 52,
- 59, 274, 274, 59, 247, 60, 274, 274, 274, 62,
- 223, 224, 49, 226, 58, 227, 54, 64, 230, 220,
- 214, 216, 226, 212, 213, 215, 219, 274, 68, 274,
- 274, 97, 274, 0, 0, 274, 233, 274, 274, 274,
- 274, 274, 274, 87, 243, 0, 274, 91, 97, 112,
- 0, 231, 274, 274, 274, 230, 274, 229, 216, 207,
- 202, 0, 201, 206, 215, 199, 207, 0, 199, 189,
- 190, 206, 194, 190, 202, 188, 189, 185, 194, 193,
+ 0, 0, 306, 307, 55, 57, 283, 0, 0, 282,
+ 53, 307, 307, 281, 50, 307, 49, 47, 57, 52,
+ 59, 307, 307, 59, 280, 60, 307, 307, 307, 62,
+ 256, 257, 49, 259, 58, 260, 54, 64, 263, 253,
+ 247, 249, 259, 245, 246, 248, 246, 60, 307, 68,
+ 307, 307, 97, 307, 0, 0, 307, 266, 307, 307,
+ 307, 307, 307, 307, 91, 276, 0, 307, 93, 97,
+ 112, 0, 264, 307, 307, 307, 263, 307, 262, 249,
+ 76, 236, 0, 235, 240, 249, 233, 241, 0, 233,
+ 223, 224, 240, 228, 224, 236, 74, 224, 220, 229,
- 274, 208, 0, 274, 120, 218, 212, 0, 93, 127,
- 118, 125, 0, 274, 274, 274, 197, 100, 194, 191,
- 178, 176, 0, 185, 173, 177, 175, 180, 183, 0,
- 184, 167, 166, 179, 177, 171, 274, 131, 133, 274,
- 140, 138, 142, 171, 162, 170, 177, 0, 172, 0,
- 161, 157, 155, 0, 154, 156, 162, 154, 166, 0,
- 154, 162, 144, 146, 0, 0, 153, 149, 0, 0,
- 0, 146, 151, 145, 144, 147, 141, 142, 0, 138,
- 147, 0, 122, 109, 102, 0, 0, 92, 94, 0,
- 0, 86, 75, 0, 0, 84, 64, 55, 0, 59,
+ 226, 227, 226, 307, 241, 0, 307, 120, 251, 245,
+ 0, 118, 128, 130, 132, 0, 307, 307, 307, 230,
+ 225, 107, 226, 223, 210, 208, 0, 217, 205, 209,
+ 207, 212, 215, 0, 216, 214, 199, 197, 196, 209,
+ 207, 211, 200, 192, 307, 138, 140, 307, 147, 145,
+ 149, 199, 192, 189, 197, 204, 0, 199, 0, 188,
+ 184, 182, 0, 181, 183, 189, 183, 180, 179, 191,
+ 0, 179, 174, 186, 185, 151, 153, 0, 184, 0,
+ 175, 171, 0, 0, 0, 168, 173, 167, 166, 169,
+ 172, 167, 161, 162, 168, 0, 162, 162, 155, 169,
- 46, 32, 0, 274, 162, 165, 168, 173, 178, 180
+ 0, 157, 156, 161, 158, 165, 0, 0, 155, 155,
+ 152, 146, 153, 0, 0, 139, 117, 99, 96, 0,
+ 107, 99, 0, 0, 101, 86, 0, 0, 0, 64,
+ 59, 0, 0, 64, 46, 32, 0, 307, 169, 172,
+ 175, 180, 185, 187
} ;
-static yyconst flex_int16_t yy_def[211] =
+static yyconst flex_int16_t yy_def[245] =
{ 0,
- 204, 1, 204, 204, 204, 204, 204, 205, 206, 204,
- 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
- 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
- 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 204, 204, 204,
- 204, 204, 204, 207, 206, 204, 204, 204, 204, 204,
- 204, 204, 204, 204, 208, 209, 204, 204, 204, 204,
- 210, 204, 204, 204, 204, 204, 204, 204, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
+ 238, 1, 238, 238, 238, 238, 238, 239, 240, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 238, 238,
+ 238, 238, 238, 238, 241, 240, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 242, 243, 238, 238, 238,
+ 238, 244, 238, 238, 238, 238, 238, 238, 238, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
- 204, 204, 207, 204, 204, 208, 208, 209, 204, 204,
- 204, 204, 210, 204, 204, 204, 206, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 204, 204, 204, 204,
- 204, 204, 204, 206, 206, 206, 206, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
- 206, 206, 204, 204, 206, 206, 206, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
+ 240, 240, 240, 238, 238, 241, 238, 238, 242, 242,
+ 243, 238, 238, 238, 238, 244, 238, 238, 238, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 238, 238, 238, 238, 238, 238,
+ 238, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 238, 238, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
- 206, 206, 206, 0, 204, 204, 204, 204, 204, 204
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 0, 238, 238,
+ 238, 238, 238, 238
} ;
-static yyconst flex_int16_t yy_nxt[331] =
+static yyconst flex_uint16_t yy_nxt[364] =
{ 0,
4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 9, 9, 28, 29, 30, 9,
31, 32, 33, 34, 35, 9, 36, 37, 9, 38,
- 39, 40, 41, 42, 43, 44, 45, 46, 9, 47,
- 9, 9, 48, 49, 50, 51, 52, 52, 52, 52,
- 57, 60, 62, 64, 64, 203, 68, 65, 69, 69,
- 63, 61, 66, 68, 58, 69, 69, 70, 67, 72,
- 73, 75, 76, 77, 70, 70, 81, 84, 88, 101,
- 78, 82, 70, 90, 202, 89, 201, 85, 52, 52,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 9, 9, 49, 50, 51, 52, 53, 53, 53, 53,
+ 58, 61, 63, 65, 65, 237, 69, 66, 70, 70,
+ 64, 62, 67, 69, 59, 70, 70, 71, 68, 73,
+ 74, 76, 77, 78, 71, 71, 82, 85, 89, 104,
+ 79, 83, 71, 91, 236, 90, 102, 86, 53, 53,
- 86, 200, 71, 64, 64, 199, 91, 109, 109, 109,
- 109, 68, 105, 69, 69, 198, 110, 197, 141, 196,
- 105, 102, 70, 111, 110, 111, 141, 195, 112, 112,
- 70, 138, 194, 138, 112, 112, 139, 139, 142, 193,
- 142, 112, 112, 143, 143, 145, 146, 139, 139, 139,
- 139, 163, 192, 163, 143, 143, 164, 164, 143, 143,
- 164, 164, 164, 164, 54, 191, 54, 55, 55, 55,
- 103, 103, 103, 106, 106, 106, 106, 106, 108, 190,
- 108, 108, 108, 113, 113, 189, 188, 187, 186, 185,
- 184, 183, 182, 181, 180, 179, 178, 177, 176, 175,
+ 87, 235, 72, 136, 103, 234, 92, 65, 65, 112,
+ 112, 69, 121, 70, 70, 233, 108, 122, 113, 137,
+ 138, 105, 71, 114, 108, 114, 113, 232, 115, 115,
+ 71, 146, 231, 146, 112, 112, 147, 147, 230, 150,
+ 229, 150, 228, 149, 151, 151, 115, 115, 115, 115,
+ 227, 149, 154, 155, 147, 147, 147, 147, 176, 226,
+ 176, 151, 151, 177, 177, 151, 151, 177, 177, 177,
+ 177, 55, 225, 55, 56, 56, 56, 106, 106, 106,
+ 109, 109, 109, 109, 109, 111, 224, 111, 111, 111,
+ 116, 116, 223, 222, 221, 220, 219, 218, 217, 216,
- 174, 173, 172, 171, 170, 169, 168, 167, 166, 165,
- 162, 161, 160, 159, 158, 157, 156, 155, 154, 153,
- 152, 151, 150, 149, 148, 147, 144, 140, 107, 137,
- 136, 135, 134, 133, 132, 131, 130, 129, 128, 127,
- 126, 125, 124, 123, 122, 121, 120, 119, 118, 117,
- 116, 115, 114, 107, 104, 100, 99, 98, 97, 96,
- 95, 94, 93, 92, 87, 83, 80, 79, 74, 59,
- 56, 53, 204, 3, 204, 204, 204, 204, 204, 204,
- 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
- 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
+ 215, 214, 213, 212, 211, 210, 209, 208, 207, 206,
+ 205, 204, 203, 202, 201, 200, 199, 198, 197, 196,
+ 195, 194, 193, 192, 191, 190, 189, 188, 187, 186,
+ 185, 184, 183, 182, 181, 180, 179, 178, 175, 174,
+ 173, 172, 171, 170, 169, 168, 167, 166, 165, 164,
+ 163, 162, 161, 160, 159, 158, 157, 156, 153, 152,
+ 148, 110, 145, 144, 143, 142, 141, 140, 139, 135,
+ 134, 133, 132, 131, 130, 129, 128, 127, 126, 125,
+ 124, 123, 120, 119, 118, 117, 110, 107, 101, 100,
+ 99, 98, 97, 96, 95, 94, 93, 88, 84, 81,
- 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
- 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
- 204, 204, 204, 204, 204, 204, 204, 204, 204, 204
+ 80, 75, 60, 57, 54, 238, 3, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238
} ;
-static yyconst flex_int16_t yy_chk[331] =
+static yyconst flex_int16_t yy_chk[364] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -545,46 +578,50 @@
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 5, 5, 6, 6,
- 11, 15, 17, 18, 18, 202, 20, 19, 20, 20,
+ 11, 15, 17, 18, 18, 236, 20, 19, 20, 20,
17, 15, 19, 21, 11, 21, 21, 20, 19, 24,
- 24, 26, 26, 30, 21, 20, 33, 35, 37, 49,
- 30, 33, 21, 38, 201, 37, 200, 35, 52, 52,
+ 24, 26, 26, 30, 21, 20, 33, 35, 37, 50,
+ 30, 33, 21, 38, 235, 37, 48, 35, 53, 53,
- 35, 198, 20, 64, 64, 197, 38, 68, 68, 109,
- 109, 69, 64, 69, 69, 196, 68, 193, 109, 192,
- 64, 49, 69, 70, 68, 70, 109, 189, 70, 70,
- 69, 105, 188, 105, 111, 111, 105, 105, 110, 185,
- 110, 112, 112, 110, 110, 118, 118, 138, 138, 139,
- 139, 141, 184, 141, 142, 142, 141, 141, 143, 143,
- 163, 163, 164, 164, 205, 183, 205, 206, 206, 206,
- 207, 207, 207, 208, 208, 208, 208, 208, 209, 181,
- 209, 209, 209, 210, 210, 180, 178, 177, 176, 175,
- 174, 173, 172, 168, 167, 162, 161, 159, 158, 157,
+ 35, 234, 20, 97, 48, 231, 38, 65, 65, 69,
+ 69, 70, 81, 70, 70, 230, 65, 81, 69, 97,
+ 97, 50, 70, 71, 65, 71, 69, 226, 71, 71,
+ 70, 108, 225, 108, 112, 112, 108, 108, 222, 113,
+ 221, 113, 219, 112, 113, 113, 114, 114, 115, 115,
+ 218, 112, 122, 122, 146, 146, 147, 147, 149, 217,
+ 149, 150, 150, 149, 149, 151, 151, 176, 176, 177,
+ 177, 239, 216, 239, 240, 240, 240, 241, 241, 241,
+ 242, 242, 242, 242, 242, 243, 213, 243, 243, 243,
+ 244, 244, 212, 211, 210, 209, 206, 205, 204, 203,
- 156, 155, 153, 152, 151, 149, 147, 146, 145, 144,
- 136, 135, 134, 133, 132, 131, 129, 128, 127, 126,
- 125, 124, 122, 121, 120, 119, 117, 107, 106, 102,
- 100, 99, 98, 97, 96, 95, 94, 93, 92, 91,
- 90, 89, 87, 86, 85, 84, 83, 81, 80, 79,
- 78, 76, 72, 65, 57, 47, 46, 45, 44, 43,
- 42, 41, 40, 39, 36, 34, 32, 31, 25, 14,
- 10, 7, 3, 204, 204, 204, 204, 204, 204, 204,
- 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
- 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
+ 202, 200, 199, 198, 197, 195, 194, 193, 192, 191,
+ 190, 189, 188, 187, 186, 182, 181, 179, 175, 174,
+ 173, 172, 170, 169, 168, 167, 166, 165, 164, 162,
+ 161, 160, 158, 156, 155, 154, 153, 152, 144, 143,
+ 142, 141, 140, 139, 138, 137, 136, 135, 133, 132,
+ 131, 130, 129, 128, 126, 125, 124, 123, 121, 120,
+ 110, 109, 105, 103, 102, 101, 100, 99, 98, 96,
+ 95, 94, 93, 92, 91, 90, 88, 87, 86, 85,
+ 84, 82, 80, 79, 77, 73, 66, 58, 47, 46,
+ 45, 44, 43, 42, 41, 40, 39, 36, 34, 32,
- 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
- 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
- 204, 204, 204, 204, 204, 204, 204, 204, 204, 204
+ 31, 25, 14, 10, 7, 3, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
+ 238, 238, 238
} ;
/* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[85] =
+static yyconst flex_int32_t yy_rule_can_match_eol[90] =
{ 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 1, 0, 0, };
+ 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, };
/* The intent behind this definition is that it'll catch
* any uses of REJECT which flex missed.
@@ -607,7 +644,7 @@
*/
#define YY_NO_UNISTD_H 1
-#line 605 "lex.sksl.c"
+#line 642 "lex.sksl.c"
#define INITIAL 0
@@ -636,7 +673,7 @@
size_t yy_buffer_stack_max; /**< capacity of stack. */
YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
char yy_hold_char;
- yy_size_t yy_n_chars;
+ int yy_n_chars;
yy_size_t yyleng_r;
char *yy_c_buf_p;
int yy_init;
@@ -678,11 +715,11 @@
FILE *skslget_in (yyscan_t yyscanner );
-void skslset_in (FILE * in_str ,yyscan_t yyscanner );
+void skslset_in (FILE * _in_str ,yyscan_t yyscanner );
FILE *skslget_out (yyscan_t yyscanner );
-void skslset_out (FILE * out_str ,yyscan_t yyscanner );
+void skslset_out (FILE * _out_str ,yyscan_t yyscanner );
yy_size_t skslget_leng (yyscan_t yyscanner );
@@ -690,7 +727,11 @@
int skslget_lineno (yyscan_t yyscanner );
-void skslset_lineno (int line_number ,yyscan_t yyscanner );
+void skslset_lineno (int _line_number ,yyscan_t yyscanner );
+
+int skslget_column (yyscan_t yyscanner );
+
+void skslset_column (int _column_no ,yyscan_t yyscanner );
/* Macros after this point can all be overridden by user definitions in
* section 1.
@@ -704,8 +745,12 @@
#endif
#endif
+#ifndef YY_NO_UNPUT
+
static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner);
+#endif
+
#ifndef yytext_ptr
static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
#endif
@@ -726,7 +771,12 @@
/* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
#endif
/* Copy whatever the last rule matched to the standard output. */
@@ -734,7 +784,7 @@
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
-#define ECHO fwrite( yytext, yyleng, 1, yyout )
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
#endif
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
@@ -745,7 +795,7 @@
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
int c = '*'; \
- yy_size_t n; \
+ size_t n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
@@ -813,7 +863,7 @@
/* Code executed at the end of each rule. */
#ifndef YY_BREAK
-#define YY_BREAK break;
+#define YY_BREAK /*LINTED*/break;
#endif
#define YY_RULE_SETUP \
@@ -823,16 +873,11 @@
*/
YY_DECL
{
- register yy_state_type yy_current_state;
- register char *yy_cp, *yy_bp;
- register int yy_act;
+ yy_state_type yy_current_state;
+ char *yy_cp, *yy_bp;
+ int yy_act;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-#line 23 "sksl.flex"
-
-
-#line 829 "lex.sksl.c"
-
if ( !yyg->yy_init )
{
yyg->yy_init = 1;
@@ -859,7 +904,13 @@
sksl_load_buffer_state(yyscanner );
}
- while ( 1 ) /* loops until end-of-file is reached */
+ {
+#line 23 "sksl.flex"
+
+
+#line 906 "lex.sksl.c"
+
+ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
{
yy_cp = yyg->yy_c_buf_p;
@@ -875,7 +926,7 @@
yy_match:
do
{
- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
if ( yy_accept[yy_current_state] )
{
yyg->yy_last_accepting_state = yy_current_state;
@@ -884,13 +935,13 @@
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 205 )
+ if ( yy_current_state >= 239 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
- while ( yy_current_state != 204 );
+ while ( yy_current_state != 238 );
yy_cp = yyg->yy_last_accepting_cpos;
yy_current_state = yyg->yy_last_accepting_state;
@@ -1055,296 +1106,321 @@
case 27:
YY_RULE_SETUP
#line 77 "sksl.flex"
-{ return SkSL::Token::STRUCT; }
+{ return SkSL::Token::READONLY; }
YY_BREAK
case 28:
YY_RULE_SETUP
#line 79 "sksl.flex"
-{ return SkSL::Token::LAYOUT; }
+{ return SkSL::Token::WRITEONLY; }
YY_BREAK
case 29:
YY_RULE_SETUP
#line 81 "sksl.flex"
-{ return SkSL::Token::PRECISION; }
+{ return SkSL::Token::COHERENT; }
YY_BREAK
case 30:
YY_RULE_SETUP
#line 83 "sksl.flex"
-{ return SkSL::Token::IDENTIFIER; }
+{ return SkSL::Token::VOLATILE; }
YY_BREAK
case 31:
YY_RULE_SETUP
#line 85 "sksl.flex"
-{ return SkSL::Token::DIRECTIVE; }
+{ return SkSL::Token::RESTRICT; }
YY_BREAK
case 32:
YY_RULE_SETUP
#line 87 "sksl.flex"
-{ return SkSL::Token::LPAREN; }
+{ return SkSL::Token::STRUCT; }
YY_BREAK
case 33:
YY_RULE_SETUP
#line 89 "sksl.flex"
-{ return SkSL::Token::RPAREN; }
+{ return SkSL::Token::LAYOUT; }
YY_BREAK
case 34:
YY_RULE_SETUP
#line 91 "sksl.flex"
-{ return SkSL::Token::LBRACE; }
+{ return SkSL::Token::PRECISION; }
YY_BREAK
case 35:
YY_RULE_SETUP
#line 93 "sksl.flex"
-{ return SkSL::Token::RBRACE; }
+{ return SkSL::Token::IDENTIFIER; }
YY_BREAK
case 36:
YY_RULE_SETUP
#line 95 "sksl.flex"
-{ return SkSL::Token::LBRACKET; }
+{ return SkSL::Token::DIRECTIVE; }
YY_BREAK
case 37:
YY_RULE_SETUP
#line 97 "sksl.flex"
-{ return SkSL::Token::RBRACKET; }
+{ return SkSL::Token::LPAREN; }
YY_BREAK
case 38:
YY_RULE_SETUP
#line 99 "sksl.flex"
-{ return SkSL::Token::DOT; }
+{ return SkSL::Token::RPAREN; }
YY_BREAK
case 39:
YY_RULE_SETUP
#line 101 "sksl.flex"
-{ return SkSL::Token::COMMA; }
+{ return SkSL::Token::LBRACE; }
YY_BREAK
case 40:
YY_RULE_SETUP
#line 103 "sksl.flex"
-{ return SkSL::Token::PLUSPLUS; }
+{ return SkSL::Token::RBRACE; }
YY_BREAK
case 41:
YY_RULE_SETUP
#line 105 "sksl.flex"
-{ return SkSL::Token::MINUSMINUS; }
+{ return SkSL::Token::LBRACKET; }
YY_BREAK
case 42:
YY_RULE_SETUP
#line 107 "sksl.flex"
-{ return SkSL::Token::PLUS; }
+{ return SkSL::Token::RBRACKET; }
YY_BREAK
case 43:
YY_RULE_SETUP
#line 109 "sksl.flex"
-{ return SkSL::Token::MINUS; }
+{ return SkSL::Token::DOT; }
YY_BREAK
case 44:
YY_RULE_SETUP
#line 111 "sksl.flex"
-{ return SkSL::Token::STAR; }
+{ return SkSL::Token::COMMA; }
YY_BREAK
case 45:
YY_RULE_SETUP
#line 113 "sksl.flex"
-{ return SkSL::Token::SLASH; }
+{ return SkSL::Token::PLUSPLUS; }
YY_BREAK
case 46:
YY_RULE_SETUP
#line 115 "sksl.flex"
-{ return SkSL::Token::PERCENT; }
+{ return SkSL::Token::MINUSMINUS; }
YY_BREAK
case 47:
YY_RULE_SETUP
#line 117 "sksl.flex"
-{ return SkSL::Token::SHL; }
+{ return SkSL::Token::PLUS; }
YY_BREAK
case 48:
YY_RULE_SETUP
#line 119 "sksl.flex"
-{ return SkSL::Token::SHR; }
+{ return SkSL::Token::MINUS; }
YY_BREAK
case 49:
YY_RULE_SETUP
#line 121 "sksl.flex"
-{ return SkSL::Token::BITWISEOR; }
+{ return SkSL::Token::STAR; }
YY_BREAK
case 50:
YY_RULE_SETUP
#line 123 "sksl.flex"
-{ return SkSL::Token::BITWISEXOR; }
+{ return SkSL::Token::SLASH; }
YY_BREAK
case 51:
YY_RULE_SETUP
#line 125 "sksl.flex"
-{ return SkSL::Token::BITWISEAND; }
+{ return SkSL::Token::PERCENT; }
YY_BREAK
case 52:
YY_RULE_SETUP
#line 127 "sksl.flex"
-{ return SkSL::Token::BITWISENOT; }
+{ return SkSL::Token::SHL; }
YY_BREAK
case 53:
YY_RULE_SETUP
#line 129 "sksl.flex"
-{ return SkSL::Token::LOGICALOR; }
+{ return SkSL::Token::SHR; }
YY_BREAK
case 54:
YY_RULE_SETUP
#line 131 "sksl.flex"
-{ return SkSL::Token::LOGICALXOR; }
+{ return SkSL::Token::BITWISEOR; }
YY_BREAK
case 55:
YY_RULE_SETUP
#line 133 "sksl.flex"
-{ return SkSL::Token::LOGICALAND; }
+{ return SkSL::Token::BITWISEXOR; }
YY_BREAK
case 56:
YY_RULE_SETUP
#line 135 "sksl.flex"
-{ return SkSL::Token::LOGICALNOT; }
+{ return SkSL::Token::BITWISEAND; }
YY_BREAK
case 57:
YY_RULE_SETUP
#line 137 "sksl.flex"
-{ return SkSL::Token::QUESTION; }
+{ return SkSL::Token::BITWISENOT; }
YY_BREAK
case 58:
YY_RULE_SETUP
#line 139 "sksl.flex"
-{ return SkSL::Token::COLON; }
+{ return SkSL::Token::LOGICALOR; }
YY_BREAK
case 59:
YY_RULE_SETUP
#line 141 "sksl.flex"
-{ return SkSL::Token::EQ; }
+{ return SkSL::Token::LOGICALXOR; }
YY_BREAK
case 60:
YY_RULE_SETUP
#line 143 "sksl.flex"
-{ return SkSL::Token::EQEQ; }
+{ return SkSL::Token::LOGICALAND; }
YY_BREAK
case 61:
YY_RULE_SETUP
#line 145 "sksl.flex"
-{ return SkSL::Token::NEQ; }
+{ return SkSL::Token::LOGICALNOT; }
YY_BREAK
case 62:
YY_RULE_SETUP
#line 147 "sksl.flex"
-{ return SkSL::Token::GT; }
+{ return SkSL::Token::QUESTION; }
YY_BREAK
case 63:
YY_RULE_SETUP
#line 149 "sksl.flex"
-{ return SkSL::Token::LT; }
+{ return SkSL::Token::COLON; }
YY_BREAK
case 64:
YY_RULE_SETUP
#line 151 "sksl.flex"
-{ return SkSL::Token::GTEQ; }
+{ return SkSL::Token::EQ; }
YY_BREAK
case 65:
YY_RULE_SETUP
#line 153 "sksl.flex"
-{ return SkSL::Token::LTEQ; }
+{ return SkSL::Token::EQEQ; }
YY_BREAK
case 66:
YY_RULE_SETUP
#line 155 "sksl.flex"
-{ return SkSL::Token::PLUSEQ; }
+{ return SkSL::Token::NEQ; }
YY_BREAK
case 67:
YY_RULE_SETUP
#line 157 "sksl.flex"
-{ return SkSL::Token::MINUSEQ; }
+{ return SkSL::Token::GT; }
YY_BREAK
case 68:
YY_RULE_SETUP
#line 159 "sksl.flex"
-{ return SkSL::Token::STAREQ; }
+{ return SkSL::Token::LT; }
YY_BREAK
case 69:
YY_RULE_SETUP
#line 161 "sksl.flex"
-{ return SkSL::Token::SLASHEQ; }
+{ return SkSL::Token::GTEQ; }
YY_BREAK
case 70:
YY_RULE_SETUP
#line 163 "sksl.flex"
-{ return SkSL::Token::PERCENTEQ; }
+{ return SkSL::Token::LTEQ; }
YY_BREAK
case 71:
YY_RULE_SETUP
#line 165 "sksl.flex"
-{ return SkSL::Token::SHLEQ; }
+{ return SkSL::Token::PLUSEQ; }
YY_BREAK
case 72:
YY_RULE_SETUP
#line 167 "sksl.flex"
-{ return SkSL::Token::SHREQ; }
+{ return SkSL::Token::MINUSEQ; }
YY_BREAK
case 73:
YY_RULE_SETUP
#line 169 "sksl.flex"
-{ return SkSL::Token::BITWISEOREQ; }
+{ return SkSL::Token::STAREQ; }
YY_BREAK
case 74:
YY_RULE_SETUP
#line 171 "sksl.flex"
-{ return SkSL::Token::BITWISEXOREQ; }
+{ return SkSL::Token::SLASHEQ; }
YY_BREAK
case 75:
YY_RULE_SETUP
#line 173 "sksl.flex"
-{ return SkSL::Token::BITWISEANDEQ; }
+{ return SkSL::Token::PERCENTEQ; }
YY_BREAK
case 76:
YY_RULE_SETUP
#line 175 "sksl.flex"
-{ return SkSL::Token::LOGICALOREQ; }
+{ return SkSL::Token::SHLEQ; }
YY_BREAK
case 77:
YY_RULE_SETUP
#line 177 "sksl.flex"
-{ return SkSL::Token::LOGICALXOREQ; }
+{ return SkSL::Token::SHREQ; }
YY_BREAK
case 78:
YY_RULE_SETUP
#line 179 "sksl.flex"
-{ return SkSL::Token::LOGICALANDEQ; }
+{ return SkSL::Token::BITWISEOREQ; }
YY_BREAK
case 79:
YY_RULE_SETUP
#line 181 "sksl.flex"
-{ return SkSL::Token::SEMICOLON; }
+{ return SkSL::Token::BITWISEXOREQ; }
YY_BREAK
case 80:
YY_RULE_SETUP
#line 183 "sksl.flex"
-/* line comment */
+{ return SkSL::Token::BITWISEANDEQ; }
YY_BREAK
case 81:
-/* rule 81 can match eol */
YY_RULE_SETUP
#line 185 "sksl.flex"
-/* block comment */
+{ return SkSL::Token::LOGICALOREQ; }
YY_BREAK
case 82:
-/* rule 82 can match eol */
YY_RULE_SETUP
#line 187 "sksl.flex"
-/* whitespace */
+{ return SkSL::Token::LOGICALXOREQ; }
YY_BREAK
case 83:
YY_RULE_SETUP
#line 189 "sksl.flex"
-{ return SkSL::Token::INVALID_TOKEN; }
+{ return SkSL::Token::LOGICALANDEQ; }
YY_BREAK
case 84:
YY_RULE_SETUP
#line 191 "sksl.flex"
+{ return SkSL::Token::SEMICOLON; }
+ YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 193 "sksl.flex"
+/* line comment */
+ YY_BREAK
+case 86:
+/* rule 86 can match eol */
+YY_RULE_SETUP
+#line 195 "sksl.flex"
+/* block comment */
+ YY_BREAK
+case 87:
+/* rule 87 can match eol */
+YY_RULE_SETUP
+#line 197 "sksl.flex"
+/* whitespace */
+ YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 199 "sksl.flex"
+{ return SkSL::Token::INVALID_TOKEN; }
+ YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 201 "sksl.flex"
ECHO;
YY_BREAK
-#line 1342 "lex.sksl.c"
+#line 1418 "lex.sksl.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
@@ -1476,6 +1552,7 @@
"fatal flex scanner internal error--no action found" );
} /* end of action switch */
} /* end of scanning one token */
+ } /* end of user's declarations */
} /* end of sksllex */
/* yy_get_next_buffer - try to read in a new buffer
@@ -1488,9 +1565,9 @@
static int yy_get_next_buffer (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
- register char *source = yyg->yytext_ptr;
- register int number_to_move, i;
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = yyg->yytext_ptr;
+ yy_size_t number_to_move, i;
int ret_val;
if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
@@ -1519,7 +1596,7 @@
/* Try to read more data. */
/* First move last chars to start of buffer. */
- number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+ number_to_move = (yy_size_t) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
for ( i = 0; i < number_to_move; ++i )
*(dest++) = *(source++);
@@ -1539,7 +1616,7 @@
{ /* Not enough room in the buffer - grow it. */
/* just a shorter name for the current buffer */
- YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
int yy_c_buf_p_offset =
(int) (yyg->yy_c_buf_p - b->yy_ch_buf);
@@ -1601,9 +1678,9 @@
else
ret_val = EOB_ACT_CONTINUE_SCAN;
- if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
/* Extend the array by 50%, plus the number we really need. */
- yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) skslrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
@@ -1622,15 +1699,15 @@
static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
{
- register yy_state_type yy_current_state;
- register char *yy_cp;
+ yy_state_type yy_current_state;
+ char *yy_cp;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yy_current_state = yyg->yy_start;
for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
{
- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
if ( yy_accept[yy_current_state] )
{
yyg->yy_last_accepting_state = yy_current_state;
@@ -1639,7 +1716,7 @@
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 205 )
+ if ( yy_current_state >= 239 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1655,11 +1732,11 @@
*/
static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
{
- register int yy_is_jam;
+ int yy_is_jam;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
- register char *yy_cp = yyg->yy_c_buf_p;
+ char *yy_cp = yyg->yy_c_buf_p;
- register YY_CHAR yy_c = 1;
+ YY_CHAR yy_c = 1;
if ( yy_accept[yy_current_state] )
{
yyg->yy_last_accepting_state = yy_current_state;
@@ -1668,18 +1745,21 @@
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 205 )
+ if ( yy_current_state >= 239 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 204);
+ yy_is_jam = (yy_current_state == 238);
+ (void)yyg;
return yy_is_jam ? 0 : yy_current_state;
}
- static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner)
+#ifndef YY_NO_UNPUT
+
+ static void yyunput (int c, char * yy_bp , yyscan_t yyscanner)
{
- register char *yy_cp;
+ char *yy_cp;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
yy_cp = yyg->yy_c_buf_p;
@@ -1690,10 +1770,10 @@
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
{ /* need to shift things up to make room */
/* +2 for EOB chars. */
- register yy_size_t number_to_move = yyg->yy_n_chars + 2;
- register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ yy_size_t number_to_move = yyg->yy_n_chars + 2;
+ char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
- register char *source =
+ char *source =
&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
@@ -1719,6 +1799,8 @@
yyg->yy_c_buf_p = yy_cp;
}
+#endif
+
#ifndef YY_NO_INPUT
#ifdef __cplusplus
static int yyinput (yyscan_t yyscanner)
@@ -1768,7 +1850,7 @@
case EOB_ACT_END_OF_FILE:
{
if ( skslwrap(yyscanner ) )
- return 0;
+ return EOF;
if ( ! yyg->yy_did_buffer_switch_on_eof )
YY_NEW_FILE;
@@ -1879,7 +1961,7 @@
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in sksl_create_buffer()" );
- b->yy_buf_size = size;
+ b->yy_buf_size = (yy_size_t)size;
/* yy_ch_buf has to be 2 characters longer than the size given because
* we need to put in 2 end-of-buffer characters.
@@ -2040,7 +2122,7 @@
* scanner will even need a stack. We use 2 instead of 1 to avoid an
* immediate realloc on the next call.
*/
- num_to_alloc = 1;
+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
yyg->yy_buffer_stack = (struct yy_buffer_state**)skslalloc
(num_to_alloc * sizeof(struct yy_buffer_state*)
, yyscanner);
@@ -2057,7 +2139,7 @@
if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
/* Increase the buffer to prepare for a possible push. */
- int grow_size = 8 /* arbitrary grow size */;
+ yy_size_t grow_size = 8 /* arbitrary grow size */;
num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
yyg->yy_buffer_stack = (struct yy_buffer_state**)skslrealloc
@@ -2124,8 +2206,8 @@
/** Setup the input buffer state to scan the given bytes. The next call to sksllex() will
* scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
*/
@@ -2133,7 +2215,8 @@
{
YY_BUFFER_STATE b;
char *buf;
- yy_size_t n, i;
+ yy_size_t n;
+ yy_size_t i;
/* Get memory for full buffer, including space for trailing EOB's. */
n = _yybytes_len + 2;
@@ -2164,7 +2247,9 @@
static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
{
- (void) fprintf( stderr, "%s\n", msg );
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+ (void) fprintf( stderr, "%s\n", msg );
exit( YY_EXIT_FAILURE );
}
@@ -2270,51 +2355,51 @@
}
/** Set the current line number.
- * @param line_number
+ * @param _line_number line number
* @param yyscanner The scanner object.
*/
-void skslset_lineno (int line_number , yyscan_t yyscanner)
+void skslset_lineno (int _line_number , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* lineno is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "skslset_lineno called with no buffer" , yyscanner);
+ YY_FATAL_ERROR( "skslset_lineno called with no buffer" );
- yylineno = line_number;
+ yylineno = _line_number;
}
/** Set the current column.
- * @param line_number
+ * @param _column_no column number
* @param yyscanner The scanner object.
*/
-void skslset_column (int column_no , yyscan_t yyscanner)
+void skslset_column (int _column_no , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
/* column is only valid if an input buffer exists. */
if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "skslset_column called with no buffer" , yyscanner);
+ YY_FATAL_ERROR( "skslset_column called with no buffer" );
- yycolumn = column_no;
+ yycolumn = _column_no;
}
/** Set the input stream. This does not discard the current
* input buffer.
- * @param in_str A readable stream.
+ * @param _in_str A readable stream.
* @param yyscanner The scanner object.
* @see sksl_switch_to_buffer
*/
-void skslset_in (FILE * in_str , yyscan_t yyscanner)
+void skslset_in (FILE * _in_str , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyin = in_str ;
+ yyin = _in_str ;
}
-void skslset_out (FILE * out_str , yyscan_t yyscanner)
+void skslset_out (FILE * _out_str , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyout = out_str ;
+ yyout = _out_str ;
}
int skslget_debug (yyscan_t yyscanner)
@@ -2323,10 +2408,10 @@
return yy_flex_debug;
}
-void skslset_debug (int bdebug , yyscan_t yyscanner)
+void skslset_debug (int _bdebug , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yy_flex_debug = bdebug ;
+ yy_flex_debug = _bdebug ;
}
/* Accessor methods for yylval and yylloc */
@@ -2465,7 +2550,10 @@
#ifndef yytext_ptr
static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
{
- register int i;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+
+ int i;
for ( i = 0; i < n; ++i )
s1[i] = s2[i];
}
@@ -2474,7 +2562,7 @@
#ifdef YY_NEED_STRLEN
static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
{
- register int n;
+ int n;
for ( n = 0; s[n]; ++n )
;
@@ -2484,11 +2572,16 @@
void *skslalloc (yy_size_t size , yyscan_t yyscanner)
{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
return (void *) malloc( size );
}
void *skslrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+
/* The cast to (char *) in the following accommodates both
* implementations that use char* generic pointers, and those
* that use void* generic pointers. It works with the latter
@@ -2501,12 +2594,14 @@
void skslfree (void * ptr , yyscan_t yyscanner)
{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
free( (char *) ptr ); /* see skslrealloc() for (char *) cast */
}
#define YYTABLES_NAME "yytables"
-#line 191 "sksl.flex"
+#line 201 "sksl.flex"
diff --git a/src/sksl/sksl.flex b/src/sksl/sksl.flex
index 4455f50..25216bd 100644
--- a/src/sksl/sksl.flex
+++ b/src/sksl/sksl.flex
@@ -74,6 +74,16 @@
noperspective { return SkSL::Token::NOPERSPECTIVE; }
+readonly { return SkSL::Token::READONLY; }
+
+writeonly { return SkSL::Token::WRITEONLY; }
+
+coherent { return SkSL::Token::COHERENT; }
+
+volatile { return SkSL::Token::VOLATILE; }
+
+restrict { return SkSL::Token::RESTRICT; }
+
struct { return SkSL::Token::STRUCT; }
layout { return SkSL::Token::LAYOUT; }